diff --git a/.github/workflows/test_publish.yml b/.github/workflows/test_publish.yml index 8483b51..8aa40a8 100644 --- a/.github/workflows/test_publish.yml +++ b/.github/workflows/test_publish.yml @@ -71,6 +71,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 + with: + sdk: dev - name: Install dependencies run: dart pub get - name: Publish diff --git a/.gitignore b/.gitignore index 0822d40..932fa67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ # FVM Version Cache .fvm/ +.VSCodeCounter/ +.idea/ .dart_tool/ pubspec.lock @@ -131,3 +133,4 @@ app.*.symbols !**/ios/**/default.perspectivev3 !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages !/dev/ci/**/Gemfile.lock + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..58035fb --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +ffigen: + dart run ffigen --config ffigen.yaml + +coverage: + flutter test --coverage + +test: + flutter test + +copy-debug: + cp -f src/cmake-build-debug/libmnn_c_api.dylib .dart_tool/lib/libmnn_c_api.dylib diff --git a/analysis_options.yaml b/analysis_options.yaml index 09ea8d1..da8569f 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -25,6 +25,8 @@ analyzer: # test_coverage - test/.test_coverage.dart + - src/** + language: # We've seen errors tied to use of implicit operations similar to the ones described in # https://dart.dev/guides/language/analysis-options#enabling-additional-type-checks. @@ -34,6 +36,7 @@ analyzer: errors: constant_identifier_names: ignore + library_prefixes: ignore missing_required_param: error missing_return: error non_constant_identifier_names: ignore diff --git a/ffigen.yaml b/ffigen.yaml index ab6d140..ed0fab9 100644 --- a/ffigen.yaml +++ b/ffigen.yaml @@ -27,6 +27,9 @@ headers: - "src/stb_image_resize2.h" - "src/stb_image_write.h" - "src/image_process.h" + - "src/expr.h" + - "src/expr_op.h" + - "src/stdvec.h" include-directives: - "src/autotime.h" - "src/error_code.h" @@ -39,6 +42,9 @@ headers: - "src/stb_image_resize2.h" - "src/stb_image_write.h" - "src/image_process.h" + - "src/expr.h" + - "src/expr_op.h" + - "src/stdvec.h" structs: exclude: - 'halide_type_t' diff --git a/hook/build.dart b/hook/build.dart index 3723bb3..0c7bc6b 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -71,6 +71,7 @@ Future _builder(BuildInput input, BuildOutputBuilder output) async { 'MNN_BUILD_CODEGEN': 'OFF', 'MNN_ENABLE_COVERAGE': 'OFF', 'MNN_JNI': 'OFF', + "MNN_KLEIDIAI": 'OFF', ...defines, }, buildLocal: options["build_local"] as bool? ?? false, diff --git a/lib/mnn.dart b/lib/mnn.dart index 8c28d52..1deb1a9 100644 --- a/lib/mnn.dart +++ b/lib/mnn.dart @@ -10,6 +10,9 @@ export 'src/backend.dart'; export 'src/base.dart'; export 'src/constant.dart'; export 'src/exception.dart'; +export 'src/expr/expr.dart'; +export 'src/expr/utils.dart'; +export 'src/formatter.dart'; export 'src/g/mnn.g.dart' show DimensionType, diff --git a/lib/numdart.dart b/lib/numdart.dart new file mode 100644 index 0000000..8477736 --- /dev/null +++ b/lib/numdart.dart @@ -0,0 +1 @@ +export 'src/expr/op.dart'; diff --git a/lib/src/base.dart b/lib/src/base.dart index a14d69b..90e62ed 100644 --- a/lib/src/base.dart +++ b/lib/src/base.dart @@ -91,6 +91,12 @@ Future mnnRunAsync0( return completer.future; } +void MnnAssert(bool condition, String message) { + if (!condition) { + throw MNNException(message); + } +} + typedef u8 = ffi.Uint8; typedef u16 = ffi.Uint16; typedef u32 = ffi.Uint32; diff --git a/lib/src/exception.dart b/lib/src/exception.dart index c774ccd..024978c 100644 --- a/lib/src/exception.dart +++ b/lib/src/exception.dart @@ -3,6 +3,6 @@ class MNNException implements Exception { MNNException(this.message); @override String toString() { - return '(MNNException: $message)'; + return 'MNNException: $message'; } } diff --git a/lib/src/expr/expr.dart b/lib/src/expr/expr.dart new file mode 100644 index 0000000..b838892 --- /dev/null +++ b/lib/src/expr/expr.dart @@ -0,0 +1,603 @@ +/// Copyright (c) 2025, rainyl. All rights reserved. +/// Use of this source code is governed by a +/// Apache 2.0 license that can be found in the LICENSE file. + +import 'dart:ffi' as ffi; +import 'dart:typed_data'; + +import 'package:ffi/ffi.dart'; +import 'package:mnn/src/base.dart'; +import 'package:mnn/src/expr/op.dart' as op; +import 'package:mnn/src/expr/utils.dart'; +import 'package:mnn/src/g/mnn.g.dart' as C; +import 'package:mnn/src/halide_runtime.dart'; +import 'package:mnn/src/tensor.dart'; +import 'package:mnn/src/vec.dart'; + +enum MemoryType { + COPY(0), + MOVE(1), + REF(2); + + final int value; + const MemoryType(this.value); + + factory MemoryType.fromValue(int value) => switch (value) { + 0 => COPY, + 1 => MOVE, + 2 => REF, + _ => throw ArgumentError.value(value, 'value', 'Invalid ExprMemoryType value') + }; +} + +enum DimensionFormat { + NHWC(0), + NC4HW4(1), + NCHW(2); + + final int value; + const DimensionFormat(this.value); + + factory DimensionFormat.fromValue(int value) => switch (value) { + 0 => NHWC, + 1 => NC4HW4, + 2 => NCHW, + _ => throw ArgumentError.value(value, 'value', 'Invalid DimensionFormat value') + }; +} + +enum InputType { + INPUT(0), + CONSTANT(1), + TRAINABLE(2); + + final int value; + const InputType(this.value); + + factory InputType.fromValue(int value) => switch (value) { + 0 => INPUT, + 1 => CONSTANT, + 2 => TRAINABLE, + _ => throw ArgumentError.value(value, 'value', 'Invalid VARPInputType value') + }; +} + +class VariableInfo extends NativeObject { + static final _finalizer = ffi.NativeFinalizer(C.addresses.mnn_expr_Variable_Info_free); + + VariableInfo.fromPointer(ffi.Pointer ptr, {super.attach, super.externalSize}) + : super(ptr.cast()); + + factory VariableInfo.create({ + DimensionFormat order = DimensionFormat.NHWC, + List? dim, + HalideType type = HalideType.f32, + int size = 0, + }) { + final (pdim, ndim) = dim?.toNativeArrayI32() ?? (ffi.nullptr, 0); + final info = calloc() + ..ref.order = order.value + ..ref.dim = pdim + ..ref.ndim = ndim + ..ref.type = type.native.ref + ..ref.size = size; + return VariableInfo.fromPointer(info); + } + + DimensionFormat get order => DimensionFormat.fromValue(ref.order); + List get dim => ptr.cast().ref.dim.asTypedList(ref.ndim); + int get size => ref.size; + HalideType get type => HalideType.fromNative(ref.type); + int get ndim => ref.ndim; + + void syncSize() { + var size_ = 1; + final dim_ = dim; + final order_ = order; + for (int i = 0; i < dim_.length; ++i) { + if (dim_[i] <= 0) { + // Not valid + size_ = 0; + return; + } + if (order_ == DimensionFormat.NC4HW4 && i == 1) { + size_ *= (dim_[1] + 4 - 1) ~/ 4 * 4; + } else { + size_ *= dim_[i]; + } + } + ref.size = size_; + } + + C.mnn_expr_Variable_Info get ref => ptr.cast().ref; + + @override + ffi.NativeFinalizer get finalizer => _finalizer; + + @override + List get props => [ptr.address]; + + @override + void release() { + finalizer.detach(this); + C.mnn_expr_Variable_Info_free(ptr); + } + + @override + String toString() { + return "VariableInfo(order=$order, dim=$dim, size=$size, type=$type, ndim=$ndim)"; + } +} + +class Expr extends NativeObject { + static final _finalizer = ffi.NativeFinalizer(C.addresses.mnn_expr_Expr_free); + + Expr.fromPointer(C.mnn_expr_Expr_t ptr, {super.attach, super.externalSize}) : super(ptr.cast()); + + factory Expr.empty() => Expr.fromPointer(C.mnn_expr_Expr_create_empty()); + + factory Expr.fromTensor(Tensor tensor, {bool own = false}) => + Expr.fromPointer(C.mnn_expr_Expr_static_create(tensor.ptr, own)); + + factory Expr.fromVariableInfo( + VariableInfo info, + InputType type, { + ffi.Pointer? ptr, + MemoryType copy = MemoryType.COPY, + }) { + return Expr.fromPointer( + C.mnn_expr_Expr_static_create_1( + info.ptr.cast(), + ptr ?? ffi.nullptr, + type.value, + copy.value, + ), + ); + } + + String get name => C.mnn_expr_Expr_getName(ptr).cast().toDartString(); + set name(String name) { + final cname = name.toNativeUtf8().cast(); + C.mnn_expr_Expr_setName(ptr, cname); + malloc.free(cname); + } + + // const Op* get() const { + // return mOp; + // } + + List get inputs { + final p = C.mnn_expr_Expr_getInputs(ptr); + final size = C.mnn_expr_VecVARP_size(p); + final rval = List.generate(size, (index) => VARP.fromPointer(C.mnn_expr_VecVARP_at(p, index))); + C.mnn_expr_VecVARP_free(p); + return rval; + } + + int get outputSize => C.mnn_expr_Expr_getOutputSize(ptr); + bool get requireInfo => C.mnn_expr_Expr_requireInfo(ptr); + + InputType get inputType => InputType.fromValue(C.mnn_expr_Expr_inputType(ptr)); + String outputName(int index) => C.mnn_expr_Expr_getOutputName(ptr, index).cast().toDartString(); + + static void replace(Expr old, Expr newExpr) { + C.mnn_expr_Expr_static_replace(old.ptr, newExpr.ptr); + } + + // void visitOutputs(const std::function& visit); + // static void visit(EXPRP expr, const std::function& before, const std::function& after); + + // const std::vector& outputs() const { + // return mTo; + // } + // List> get outputs { + // final p = C.mnn_expr_Expr_getOutputs(ptr); + // final rval = List.generate(p.ref.size, (index) => WeakReference(Expr.fromPointer(p.ref.ptr.cast()[index]))); + // malloc.free(p); + // return rval; + // } + + VariableInfo outputInfo(int index) => VariableInfo.fromPointer(C.mnn_expr_Expr_outputInfo(ptr, index)); + + @override + ffi.NativeFinalizer get finalizer => _finalizer; + + @override + List get props => [ptr.address]; + + @override + void release() { + finalizer.detach(this); + C.mnn_expr_Expr_free(ptr); + } + + @override + String toString() { + return "Expr(name=$name, inputType=$inputType, outputSize=$outputSize, requireInfo=$requireInfo)"; + } +} + +class VARP extends NativeObject { + static final _finalizer = ffi.NativeFinalizer(C.addresses.mnn_expr_VARP_free); + + VARP.fromPointer(C.VARP_t ptr, {super.attach, super.externalSize}) : super(ptr.cast()); + + factory VARP.empty() => VARP.fromPointer(C.mnn_expr_VARP_create_empty()); + + factory VARP.copyFrom(VARP varp) => VARP.fromPointer(C.mnn_expr_VARP_create_VARP(varp.ptr)); + + factory VARP.create(Expr expr, {int index = 0}) => + VARP.fromPointer(C.mnn_expr_VARP_static_create_EXPRP(expr.ptr, index)); + + static VARP scalar(num value) => op.scalar(value); + + static VARP list( + Iterable data, { + DimensionFormat format = DimensionFormat.NHWC, + }) => + op.constant(data, [data.length], format: format); + + static VARP list2D( + Iterable> data, { + DimensionFormat format = DimensionFormat.NHWC, + }) => + op.constant(data.expand((e) => e), [data.length, data.first.length], format: format); + + static VARP list3D( + Iterable>> data, { + DimensionFormat format = DimensionFormat.NHWC, + }) => + op.constant( + data.expand((e) => e.expand((e) => e)), + [data.length, data.first.length, data.first.first.length], + format: format, + ); + + static VARP list4D( + Iterable>>> data, { + DimensionFormat format = DimensionFormat.NHWC, + }) => + op.constant( + data.expand((e) => e.expand((e) => e.expand((e) => e))), + [data.length, data.first.length, data.first.first.length, data.first.first.first.length], + format: format, + ); + + static VARP listND( + Iterable data, + Iterable shape, { + DimensionFormat format = DimensionFormat.NHWC, + }) => + op.constant(data, shape, format: format); + + VARP astype() => op.cast(this); + + String getName() => C.mnn_expr_VARP_getName(ptr).cast().toDartString(); + void setName(String name) { + final cname = name.toNativeUtf8().cast(); + C.mnn_expr_VARP_setName(ptr, cname); + malloc.free(cname); + } + + bool setDevicePtr(ffi.Pointer devicePtr, int memoryType) => + C.mnn_expr_VARP_setDevicePtr(ptr, devicePtr, memoryType); + bool copyToDevicePtr(ffi.Pointer devicePtr, int memoryType) => + C.mnn_expr_VARP_copyToDevicePtr(ptr, devicePtr, memoryType); + + // this will return a new shared_ptr of internel shared_ptr + // the refcount will increase and safe to dispose + (Expr expr, int index) get expr { + final p = C.mnn_expr_VARP_getExpr(ptr); + final rval = (Expr.fromPointer(p.ref.expr), p.ref.index); + malloc.free(p); + return rval; + } + + VariableInfo getInfo() { + return VariableInfo.fromPointer(C.mnn_expr_VARP_getInfo(ptr)); + } + + bool resize(List dims) { + final cdims = dims.i32; + final rval = C.mnn_expr_VARP_resize(ptr, cdims.ptr); + cdims.dispose(); + return rval; + } + + ffi.Pointer readMap() => C.mnn_expr_VARP_readMap(ptr).cast(); + ffi.Pointer writeMap() => C.mnn_expr_VARP_writeMap(ptr).cast(); + + void unMap() => C.mnn_expr_VARP_unMap(ptr); + + bool input(VARP src) => C.mnn_expr_VARP_input(ptr, src.ptr); + + static void replace(VARP dst, VARP src) => C.mnn_expr_VARP_static_replace(dst.ptr, src.ptr); + + // static std::vector load(const char* fileName); + static List loadFromFile(String fileName) { + final cname = fileName.toNativeUtf8().cast(); + final p = C.mnn_expr_VARP_static_load(cname); + malloc.free(cname); + final size = C.mnn_expr_VecVARP_size(p); + final rval = List.generate(size, (index) => VARP.fromPointer(C.mnn_expr_VecVARP_at(p, index))); + C.mnn_expr_VecVARP_free(p); + return rval; + } + + // static std::map loadMap(const char* fileName); + static Map loadMapFromFile(String fileName) { + final cname = fileName.toNativeUtf8().cast(); + final p = C.mnn_expr_VARP_static_loadMap(cname); + malloc.free(cname); + final varmap = VarMap.fromPointer(p); + final rval = varmap.toMap(); + varmap.dispose(); + return rval; + } + + // static std::vector load(const uint8_t* buffer, size_t length); + static List loadFromBuffer(Uint8List buffer) { + final pBuf = malloc(buffer.length)..asTypedList(buffer.length).setAll(0, buffer); + final p = C.mnn_expr_VARP_static_loadBuffer(pBuf, buffer.length); + malloc.free(pBuf); + + final size = C.mnn_expr_VecVARP_size(p); + final rval = List.generate(size, (index) => VARP.fromPointer(C.mnn_expr_VecVARP_at(p, index))); + C.mnn_expr_VecVARP_free(p); + return rval; + } + + // static std::map loadMap(const uint8_t* buffer, size_t length); + static Map loadMapFromBuffer(Uint8List buffer) { + final pBuf = malloc(buffer.length)..asTypedList(buffer.length).setAll(0, buffer); + final p = C.mnn_expr_VARP_static_loadMapBuffer(pBuf, buffer.length); + malloc.free(pBuf); + + final varmap = VarMap.fromPointer(p); + final rval = varmap.toMap(); + varmap.dispose(); + return rval; + } + + // static std::pair, std::map> getInputAndOutput(const std::map& allVariable); + + // static std::vector mapToSequence(const std::map& source); + + // static std::vector getExecuteOrder(const std::vector& output); + + // static void save(const std::vector& vars, const char* fileName); + static void saveToFile(List vars, String fileName) { + final cname = fileName.toNativeUtf8().cast(); + final cVars = vars.toNativeVec(); + C.mnn_expr_VARP_static_save(cVars.ptr, cname); + malloc.free(cname); + cVars.dispose(); + } + + // static std::vector save(const std::vector& vars); + static VecI8 saveToBuffer(List vars) { + final cVars = vars.toNativeVec(); + final p = C.mnn_expr_VARP_static_saveBytes(cVars.ptr); + cVars.dispose(); + return VecI8.fromPointer(p); + } + + // static void save(const std::vector& vars, NetT* dest); + + // Pack a few Variable to compute in one pipeline + // static void prepareCompute(const std::vector& vars, bool forceCPU = false); + // static void compute(const std::vector& vars, bool forceCPU = false); + + int linkNumber() => C.mnn_expr_VARP_linkNumber(ptr); + + // const std::vector& toExprs() const; + + void setExpr(Expr expr, int index) => C.mnn_expr_VARP_setExpr(ptr, expr.ptr, index); + + Tensor getTensor() => Tensor.fromPointer(C.mnn_expr_VARP_getTensor(ptr), attach: false); + + VariableInfo get info => VariableInfo.fromPointer(C.mnn_expr_VARP_getInfo(ptr)); + + DimensionFormat get order => info.order; + List get dim => info.dim; + int get ndim => info.ndim; + HalideType get dtype => info.type; + int get size => info.size; + + List get data { + final List dataList = switch (dtype) { + HalideType.f32 => readMap().cast().asTypedList(size), + HalideType.f64 => readMap().cast().asTypedList(size), + HalideType.i32 => readMap().cast().asTypedList(size), + HalideType.u8 => readMap().cast().asTypedList(size), + HalideType.i8 => readMap().cast().asTypedList(size), + HalideType.i16 => readMap().cast().asTypedList(size), + HalideType.u16 => readMap().cast().asTypedList(size), + HalideType.i64 => readMap().cast().asTypedList(size), + HalideType.u64 => readMap().cast().asTypedList(size), + _ => throw UnimplementedError('Data type $dtype not supported'), + }; + return dataList; + } + + @override + ffi.NativeFinalizer get finalizer => _finalizer; + + @override + List get props => [ptr.address]; + + @override + void release() { + finalizer.detach(this); + C.mnn_expr_VARP_free(ptr); + } + + VARP operator +(VARP other) => VARP.fromPointer(C.mnn_expr_VARP_op_add(ptr, other.ptr)); + + VARP operator -(VARP other) => VARP.fromPointer(C.mnn_expr_VARP_op_sub(ptr, other.ptr)); + + VARP operator *(VARP other) => VARP.fromPointer(C.mnn_expr_VARP_op_mul(ptr, other.ptr)); + + VARP operator /(VARP other) => VARP.fromPointer(C.mnn_expr_VARP_op_div(ptr, other.ptr)); + + VARP mean(List dims) { + final cdims = dims.i32; + return VARP.fromPointer(C.mnn_expr_VARP_mean(ptr, cdims.ptr)); + } + + VARP sum(List dims) { + final cdims = dims.i32; + return VARP.fromPointer(C.mnn_expr_VARP_sum(ptr, cdims.ptr)); + } + + @override + bool operator ==(Object other) => other is VARP && C.mnn_expr_VARP_op_eqeq(ptr, other.ptr); + @override + int get hashCode => ptr.address.hashCode; + + bool operator <(VARP other) => C.mnn_expr_VARP_op_less(ptr, other.ptr); + bool operator <=(VARP other) => C.mnn_expr_VARP_op_lessequal(ptr, other.ptr); + + bool fix(InputType type) => C.mnn_expr_VARP_fix(ptr, type.value); + + void setOrder(DimensionFormat format) => C.mnn_expr_VARP_setOrder(ptr, format.value); + + @override + String toString() { + return 'VARP(address=0x${ptr.address.toRadixString(16)})'; + } +} + +class VecVARP extends NativeObject { + static final _finalizer = ffi.NativeFinalizer(C.addresses.mnn_expr_VecVARP_free); + + VecVARP.fromPointer(C.VecVARP_t ptr, {super.attach, super.externalSize}) : super(ptr.cast()); + + factory VecVARP.create({int size = 0, VARP? value}) { + final p = C.mnn_expr_VecVARP_create(size, value?.ptr ?? ffi.nullptr); + return VecVARP.fromPointer(p); + } + + factory VecVARP.of(List vars) { + final p = C.mnn_expr_VecVARP_create(0, ffi.nullptr); + for (int i = 0; i < vars.length; i++) { + C.mnn_expr_VecVARP_push_back(p, vars[i].ptr); + } + return VecVARP.fromPointer(p); + } + + int size() => C.mnn_expr_VecVARP_size(ptr); + int get length => C.mnn_expr_VecVARP_size(ptr); + + List toList() => List.generate(size(), (i) => VARP.fromPointer(C.mnn_expr_VecVARP_at(ptr, i))); + List asList() => List.generate(size(), (i) => VARP.fromPointer(C.mnn_expr_VecVARP_at_ref(ptr, i))); + + VARP at(int index) => VARP.fromPointer(C.mnn_expr_VecVARP_at(ptr, index)); + VARP atRef(int index) => VARP.fromPointer(C.mnn_expr_VecVARP_at_ref(ptr, index)); + void set(int index, VARP varp) => C.mnn_expr_VecVARP_set(ptr, index, varp.ptr); + void push_back(VARP varp) => C.mnn_expr_VecVARP_push_back(ptr, varp.ptr); + + @override + ffi.NativeFinalizer get finalizer => _finalizer; + + @override + List get props => [ptr.address]; + + @override + void release() { + finalizer.detach(this); + C.mnn_expr_VecVARP_free(ptr); + } + + @override + String toString() { + return "VecVARP(address=0x${ptr.address.toRadixString(16)})"; + } +} + +class VarMap extends NativeObject { + static final _finalizer = ffi.NativeFinalizer(C.addresses.mnn_expr_VecVARP_free); + + VarMap.fromPointer(C.VARMAP_t ptr, {super.attach, super.externalSize}) : super(ptr.cast()); + + factory VarMap.create() { + final p = C.mnn_expr_VARMAP_create(); + return VarMap.fromPointer(p); + } + + factory VarMap.of(Map vars) { + final p = C.mnn_expr_VARMAP_create(); + for (final MapEntry(key: key, value: value) in vars.entries) { + final ckey = key.toNativeUtf8().cast(); + C.mnn_expr_VARMAP_set(p, ckey, value.ptr); + malloc.free(ckey); + } + return VarMap.fromPointer(p); + } + + int size() => C.mnn_expr_VARMAP_size(ptr); + int get length => C.mnn_expr_VARMAP_size(ptr); + + Map toMap() { + final pKeys = C.mnn_expr_VARMAP_keys(ptr); + if (pKeys == ffi.nullptr) { + return {}; + } + final map = {}; + for (int i = 0; i < length; i++) { + final cKey = pKeys[i]; + if (cKey == ffi.nullptr) { + continue; + } + final key = cKey.cast().toDartString(); + final value = VARP.fromPointer(C.mnn_expr_VARMAP_get(ptr, cKey)); + map[key] = value; + + malloc.free(cKey); + cKey.value = 0; + } + malloc.free(pKeys); + return map; + } + + VARP at(String key) { + final ckey = key.toNativeUtf8().cast(); + final rval = VARP.fromPointer(C.mnn_expr_VARMAP_get(ptr, ckey)); + malloc.free(ckey); + return rval; + } + + VARP atRef(String key) { + final ckey = key.toNativeUtf8().cast(); + final rval = VARP.fromPointer(C.mnn_expr_VARMAP_get_ref(ptr, ckey)); + malloc.free(ckey); + return rval; + } + + void set(String key, VARP varp) { + final ckey = key.toNativeUtf8().cast(); + C.mnn_expr_VARMAP_set(ptr, ckey, varp.ptr); + malloc.free(ckey); + } + + @override + ffi.NativeFinalizer get finalizer => _finalizer; + + @override + List get props => [ptr.address]; + + @override + void release() { + finalizer.detach(this); + C.mnn_expr_VARMAP_free(ptr); + } + + @override + String toString() { + return "VarMap(address=0x${ptr.address.toRadixString(16)})"; + } +} + +extension ListVarpExtension on List { + VecVARP toNativeVec() => VecVARP.of(this); +} diff --git a/lib/src/expr/op.dart b/lib/src/expr/op.dart new file mode 100644 index 0000000..a9c5977 --- /dev/null +++ b/lib/src/expr/op.dart @@ -0,0 +1,813 @@ +// ignore_for_file: camel_case_types + +import 'dart:ffi' as ffi; + +import 'package:ffi/ffi.dart'; +import 'package:mnn/src/base.dart'; +import 'package:mnn/src/expr/expr.dart'; +import 'package:mnn/src/expr/utils.dart'; +import 'package:mnn/src/g/mnn.g.dart' as C; +import 'package:mnn/src/halide_runtime.dart'; +import 'package:mnn/src/vec.dart'; + +enum PaddingMode { + CAFFE(0), + VALID(1), + SAME(2); + + final int value; + + const PaddingMode(this.value); + + factory PaddingMode.fromValue(int value) => switch (value) { + 0 => CAFFE, + 1 => VALID, + 2 => SAME, + _ => throw ArgumentError.value(value, 'value', 'Invalid PaddingMode value'), + }; +} + +enum PoolingMode { + MAXPOOL(0), + AVEPOOL(1); + + final int value; + + const PoolingMode(this.value); + + factory PoolingMode.fromValue(int value) => switch (value) { + 0 => MAXPOOL, + 1 => AVEPOOL, + _ => throw ArgumentError.value(value, 'value', 'Invalid PoolingMode value'), + }; +} + +enum PadValueMode { + CONSTANT(0), + REFLECT(1), + SYMMETRIC(2), + EDGE(3); + + final int value; + + const PadValueMode(this.value); + + factory PadValueMode.fromValue(int value) => switch (value) { + 0 => CONSTANT, + 1 => REFLECT, + 2 => SYMMETRIC, + 3 => EDGE, + _ => throw ArgumentError.value(value, 'value', 'Invalid PadValueMode value'), + }; +} + +enum InterpolationMethod { + // BILINEAR, NEAREST + BILINEAR(0), + NEAREST(1); + + final int value; + const InterpolationMethod(this.value); + + factory InterpolationMethod.fromValue(int value) => switch (value) { + 0 => BILINEAR, + 1 => NEAREST, + _ => throw ArgumentError.value(value, 'value', 'Invalid InterpolationMethod value'), + }; +} + +enum GridSamplePaddingMode { + GRID_SAMPLE_PADDING_ZEROS(0), + GRID_SAMPLE_PADDING_BORDER(1), + GRID_SAMPLE_PADDING_REFLECTION(2); + + final int value; + const GridSamplePaddingMode(this.value); + + factory GridSamplePaddingMode.fromValue(int value) => switch (value) { + 0 => GRID_SAMPLE_PADDING_ZEROS, + 1 => GRID_SAMPLE_PADDING_BORDER, + 2 => GRID_SAMPLE_PADDING_REFLECTION, + _ => throw ArgumentError.value(value, 'value', 'Invalid GridSamplePaddingMode value'), + }; +} + +// BinaryOPs +VARP add(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Add(x.ptr, y.ptr)); +VARP subtract(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Subtract(x.ptr, y.ptr)); +VARP multiply(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Multiply(x.ptr, y.ptr)); +VARP divide(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Divide(x.ptr, y.ptr)); +VARP pow(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Pow(x.ptr, y.ptr)); +VARP minimum(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Minimum(x.ptr, y.ptr)); +VARP maximum(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Maximum(x.ptr, y.ptr)); +VARP biasAdd(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_BiasAdd(x.ptr, y.ptr)); +VARP greater(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Greater(x.ptr, y.ptr)); +VARP greaterEqual(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_GreaterEqual(x.ptr, y.ptr)); +VARP less(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Less(x.ptr, y.ptr)); +VARP floorDiv(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_FloorDiv(x.ptr, y.ptr)); +VARP squaredDifference(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_SquaredDifference(x.ptr, y.ptr)); +VARP equal(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Equal(x.ptr, y.ptr)); +VARP lessEqual(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_LessEqual(x.ptr, y.ptr)); +VARP floorMod(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_FloorMod(x.ptr, y.ptr)); +VARP atan2(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Atan2(x.ptr, y.ptr)); +VARP logicalOr(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_LogicalOr(x.ptr, y.ptr)); +VARP notEqual(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_NotEqual(x.ptr, y.ptr)); +VARP bitwiseAnd(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_BitwiseAnd(x.ptr, y.ptr)); +VARP bitwiseOr(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_BitwiseOr(x.ptr, y.ptr)); +VARP bitwiseXor(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_BitwiseXor(x.ptr, y.ptr)); + +// UnaryOPs +VARP sign(VARP x) => VARP.fromPointer(C.mnn_expr_Sign(x.ptr)); +VARP abs(VARP x) => VARP.fromPointer(C.mnn_expr_Abs(x.ptr)); +VARP negative(VARP x) => VARP.fromPointer(C.mnn_expr_Negative(x.ptr)); +VARP floor(VARP x) => VARP.fromPointer(C.mnn_expr_Floor(x.ptr)); +VARP round(VARP x) => VARP.fromPointer(C.mnn_expr_Round(x.ptr)); +VARP ceil(VARP x) => VARP.fromPointer(C.mnn_expr_Ceil(x.ptr)); +VARP square(VARP x) => VARP.fromPointer(C.mnn_expr_Square(x.ptr)); +VARP sqrt(VARP x) => VARP.fromPointer(C.mnn_expr_Sqrt(x.ptr)); +VARP rsqrt(VARP x) => VARP.fromPointer(C.mnn_expr_Rsqrt(x.ptr)); +VARP exp(VARP x) => VARP.fromPointer(C.mnn_expr_Exp(x.ptr)); +VARP log(VARP x) => VARP.fromPointer(C.mnn_expr_Log(x.ptr)); +VARP sin(VARP x) => VARP.fromPointer(C.mnn_expr_Sin(x.ptr)); +VARP sinh(VARP x) => VARP.fromPointer(C.mnn_expr_Sinh(x.ptr)); +VARP cos(VARP x) => VARP.fromPointer(C.mnn_expr_Cos(x.ptr)); +VARP cosh(VARP x) => VARP.fromPointer(C.mnn_expr_Cosh(x.ptr)); +VARP tan(VARP x) => VARP.fromPointer(C.mnn_expr_Tan(x.ptr)); +VARP tanh(VARP x) => VARP.fromPointer(C.mnn_expr_Tanh(x.ptr)); +VARP asin(VARP x) => VARP.fromPointer(C.mnn_expr_Asin(x.ptr)); +VARP asinh(VARP x) => VARP.fromPointer(C.mnn_expr_Asinh(x.ptr)); +VARP acos(VARP x) => VARP.fromPointer(C.mnn_expr_Acos(x.ptr)); +VARP acosh(VARP x) => VARP.fromPointer(C.mnn_expr_Acosh(x.ptr)); +VARP atan(VARP x) => VARP.fromPointer(C.mnn_expr_Atan(x.ptr)); +VARP atanh(VARP x) => VARP.fromPointer(C.mnn_expr_Atanh(x.ptr)); +VARP reciprocal(VARP x) => VARP.fromPointer(C.mnn_expr_Reciprocal(x.ptr)); +VARP log1p(VARP x) => VARP.fromPointer(C.mnn_expr_Log1p(x.ptr)); +VARP gelu(VARP x) => VARP.fromPointer(C.mnn_expr_Gelu(x.ptr)); +VARP sigmoid(VARP x) => VARP.fromPointer(C.mnn_expr_Sigmoid(x.ptr)); +VARP erf(VARP x) => VARP.fromPointer(C.mnn_expr_Erf(x.ptr)); +VARP erfc(VARP x) => VARP.fromPointer(C.mnn_expr_Erfc(x.ptr)); +VARP erfinv(VARP x) => VARP.fromPointer(C.mnn_expr_Erfinv(x.ptr)); +VARP expm1(VARP x) => VARP.fromPointer(C.mnn_expr_Expm1(x.ptr)); +VARP hardswish(VARP x) => VARP.fromPointer(C.mnn_expr_Hardswish(x.ptr)); +VARP silu(VARP x) => VARP.fromPointer(C.mnn_expr_Silu(x.ptr)); + +// ReduceOPs +VARP reduceSum(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceSum(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceMean(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceMean(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceMax(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceMax(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceMin(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceMin(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceProd(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceProd(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceAny(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceAny(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceAll(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceAll(x.ptr, axis.i32.ptr, keepDims)); + +VARP reduceSumMutable(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceSumMutable(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceMeanMutable(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceMeanMutable(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceMaxMutable(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceMaxMutable(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceMinMutable(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceMinMutable(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceProdMutable(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceProdMutable(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceAnyMutable(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceAnyMutable(x.ptr, axis.i32.ptr, keepDims)); +VARP reduceAllMutable(VARP x, List axis, {bool keepDims = false}) => + VARP.fromPointer(C.mnn_expr_ReduceAllMutable(x.ptr, axis.i32.ptr, keepDims)); + +// EltwiseOPs +VARP prod(VARP x, VARP y, List coeff) { + final (p, size) = coeff.toNativeArrayF32(); + final rval = VARP.fromPointer(C.mnn_expr_Prod(x.ptr, y.ptr, p, size)); + calloc.free(p); + return rval; +} + +VARP sum(VARP x, VARP y, List coeff) { + final (p, size) = coeff.toNativeArrayF32(); + final rval = VARP.fromPointer(C.mnn_expr_Sum(x.ptr, y.ptr, p, size)); + calloc.free(p); + return rval; +} + +VARP max(VARP x, VARP y, List coeff) { + final (p, size) = coeff.toNativeArrayF32(); + final rval = VARP.fromPointer(C.mnn_expr_Max(x.ptr, y.ptr, p, size)); + calloc.free(p); + return rval; +} + +VARP sub(VARP x, VARP y, List coeff) { + final (p, size) = coeff.toNativeArrayF32(); + final rval = VARP.fromPointer(C.mnn_expr_Sub(x.ptr, y.ptr, p, size)); + calloc.free(p); + return rval; +} + +VARP mod(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_Mod(x.ptr, y.ptr)); + +// OtherOPs +VARP cast(VARP x) => + VARP.fromPointer(C.mnn_expr_Cast(x.ptr, HalideType.of().native.ref)); +VARP matMul(VARP x, VARP y, {bool transposeA = false, bool transposeB = false}) => + VARP.fromPointer(C.mnn_expr_MatMul(x.ptr, y.ptr, transposeA, transposeB)); +VARP normalize(VARP x, int acrossSpatial, int channelShared, double eps, List scale) { + final (p, size) = scale.toNativeArrayF32(); + final rval = VARP.fromPointer(C.mnn_expr_Normalize(x.ptr, acrossSpatial, channelShared, eps, p, size)); + calloc.free(p); + return rval; +} + +VARP argMax(VARP x, int axis) => VARP.fromPointer(C.mnn_expr_ArgMax(x.ptr, axis)); +VARP argMin(VARP x, int axis) => VARP.fromPointer(C.mnn_expr_ArgMin(x.ptr, axis)); +VARP batchMatMul(VARP x, VARP y, {bool adjX = false, bool adjY = false}) => + VARP.fromPointer(C.mnn_expr_BatchMatMul(x.ptr, y.ptr, adjX, adjY)); +VARP unravelIndex(VARP indices, VARP dims) => + VARP.fromPointer(C.mnn_expr_UnravelIndex(indices.ptr, dims.ptr)); +VARP scatterND(VARP indices, VARP updates, VARP shape, {VARP? input, int? reduction}) => + switch ((input, reduction)) { + (null, null) => VARP.fromPointer(C.mnn_expr_ScatterNd(indices.ptr, updates.ptr, shape.ptr)), + (VARP(), null) => + VARP.fromPointer(C.mnn_expr_ScatterNd_1(indices.ptr, updates.ptr, shape.ptr, input!.ptr)), + (null, int()) => + VARP.fromPointer(C.mnn_expr_ScatterNd_2(indices.ptr, updates.ptr, shape.ptr, reduction!)), + (VARP(), int()) => + VARP.fromPointer(C.mnn_expr_ScatterNd_3(indices.ptr, updates.ptr, shape.ptr, input!.ptr, reduction!)), + }; +VARP scatterElements(VARP data, VARP indices, VARP updates, {VARP? axis, int reduction = -1}) => + switch (axis) { + null => VARP.fromPointer(C.mnn_expr_ScatterElements(data.ptr, indices.ptr, updates.ptr, reduction)), + VARP() => VARP.fromPointer( + C.mnn_expr_ScatterElements_1(data.ptr, indices.ptr, updates.ptr, axis.ptr, reduction), + ), + }; +VARP oneHot(VARP indices, VARP depth, VARP onValue, VARP offValue, int axis) => + VARP.fromPointer(C.mnn_expr_OneHot(indices.ptr, depth.ptr, onValue.ptr, offValue.ptr, axis)); +VARP broadcastTo(VARP x, VARP shape) => VARP.fromPointer(C.mnn_expr_BroadcastTo(x.ptr, shape.ptr)); +VARP linSpace(VARP start, VARP stop, VARP num) => + VARP.fromPointer(C.mnn_expr_LinSpace(start.ptr, stop.ptr, num.ptr)); +VARP randomUniform( + VARP shape, + HalideType dtype, { + double low = 0.0, + double high = 1.0, + int seed0 = 0, + int seed1 = 0, +}) => + VARP.fromPointer(C.mnn_expr_RandomUniform(shape.ptr, dtype.native.ref, low, high, seed0, seed1)); +VARP cumSum(VARP x, int axis, {bool exclusive = false, bool reverse = false}) => + VARP.fromPointer(C.mnn_expr_CumSum(x.ptr, axis, exclusive, reverse)); +VARP cumProd(VARP x, int axis) => VARP.fromPointer(C.mnn_expr_CumProd(x.ptr, axis)); +List svd(VARP x) { + final p = C.mnn_expr_Svd(x.ptr); + final size = C.mnn_expr_VecVARP_size(p); + final rval = List.generate(size, (i) => VARP.fromPointer(C.mnn_expr_VecVARP_at(p, i))); + C.mnn_expr_VecVARP_free(p); + return rval; +} + +VARP histogram(VARP x, int bin, int min, int max, int channel) => + VARP.fromPointer(C.mnn_expr_Histogram(x.ptr, bin, min, max, channel)); + +// Neural Network Ops +VARP input( + List shape, { + DimensionFormat dataFormat = DimensionFormat.NC4HW4, + HalideType dtype = HalideType.f32, +}) { + final (p, size) = shape.toNativeArrayI32(); + final rval = VARP.fromPointer(C.mnn_expr_Input(p.cast(), size, dataFormat.value, dtype.native.ref)); + calloc.free(p); + return rval; +} + +VARP clone(VARP x, {bool deepCopy = false}) => VARP.fromPointer(C.mnn_expr_Clone(x.ptr, deepCopy)); + +typedef uint8 = ffi.Uint8; +typedef uint16 = ffi.Uint16; +typedef uint32 = ffi.Uint32; +typedef uint64 = ffi.Uint64; +typedef int8 = ffi.Int8; +typedef int16 = ffi.Int16; +typedef int32 = ffi.Int32; +typedef int64 = ffi.Int64; +typedef float32 = ffi.Float; +typedef float64 = ffi.Double; + +ffi.Pointer _pointerOf(Iterable data) { + ffi.Pointer pdata; + if (T == uint8) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toInt())); + } else if (T == uint16) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toInt())); + } else if (T == uint32) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toInt())); + } else if (T == uint64) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toInt())); + } else if (T == int8) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toInt())); + } else if (T == int16) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toInt())); + } else if (T == int32) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toInt())); + } else if (T == int64) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toInt())); + } else if (T == float32) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toDouble())); + } else if (T == float64) { + pdata = calloc(data.length)..asTypedList(data.length).setAll(0, data.map((e) => e.toDouble())); + } else { + throw ArgumentError.value(T, 'T', 'Unsupported type'); + } + return pdata.cast(); +} + +VARP constant( + Iterable data, + Iterable shape, { + DimensionFormat format = DimensionFormat.NHWC, +}) { + final nElem = shape.reduce((a, b) => a * b); + MnnAssert( + data.length == nElem, + 'data.length=${data.length} must be equal to the dot product of shape=$nElem', + ); + + final pdata = _pointerOf(data); + final pshape = _pointerOf(shape); + final pvar = C.mnn_expr_Const( + pdata.cast(), + pshape.cast(), + shape.length, + format.value, + HalideType.of().native.ref, + ); + // memories of pdata will be copied internally, so here we need to free them + calloc.free(pdata); + calloc.free(pshape); + return VARP.fromPointer(pvar); +} + +VARP scalar(num value) { + final pdata = _pointerOf([value]); + final pvar = C.mnn_expr_Scalar(pdata.cast(), HalideType.of().native.ref); + calloc.free(pdata); + return VARP.fromPointer(pvar); +} + +VARP conv( + VARP weight, + VARP bias, + VARP x, { + PaddingMode pad = PaddingMode.VALID, + List stride = const [1, 1], + List dilatie = const [1, 1], + int group = 1, + List pads = const [0, 0], +}) { + final (stridePtr, strideSize) = stride.toNativeArrayI32(); + final (dilationPtr, dilationSize) = dilatie.toNativeArrayI32(); + final (padPtr, padSize) = pads.toNativeArrayI32(); + final rval = VARP.fromPointer( + C.mnn_expr_Conv( + weight.ptr, + bias.ptr, + x.ptr, + pad.value, + stridePtr.cast(), + strideSize, + dilationPtr.cast(), + dilationSize, + group, + padPtr.cast(), + padSize, + ), + ); + calloc.free(stridePtr); + calloc.free(dilationPtr); + calloc.free(padPtr); + return rval; +} + +VARP conv2d( + VARP weight, + VARP bias, + VARP x, { + PaddingMode pad = PaddingMode.VALID, + List stride = const [1, 1], + List dilatie = const [1, 1], + int group = 1, + List pads = const [0, 0], +}) => + conv(weight, bias, x, pad: pad, stride: stride, dilatie: dilatie, group: group, pads: pads); + +VARP deconv( + VARP weight, + VARP bias, + VARP x, { + PaddingMode pad = PaddingMode.VALID, + List stride = const [1, 1], + List dilatie = const [1, 1], + int group = 1, + List pads = const [0, 0], +}) { + final (stridePtr, strideSize) = stride.toNativeArrayI32(); + final (dilationPtr, dilationSize) = dilatie.toNativeArrayI32(); + final (padPtr, padSize) = pads.toNativeArrayI32(); + final rval = VARP.fromPointer( + C.mnn_expr_Deconv( + weight.ptr, + bias.ptr, + x.ptr, + pad.value, + stridePtr.cast(), + strideSize, + dilationPtr.cast(), + dilationSize, + group, + padPtr.cast(), + padSize, + ), + ); + calloc.free(stridePtr); + calloc.free(dilationPtr); + calloc.free(padPtr); + return rval; +} + +VARP conv2dTranspose( + VARP weight, + VARP bias, + VARP x, { + PaddingMode pad = PaddingMode.VALID, + List stride = const [1, 1], + List dilatie = const [1, 1], + int group = 1, + List pads = const [0, 0], +}) => + deconv(weight, bias, x, pad: pad, stride: stride, dilatie: dilatie, group: group, pads: pads); + +VARP maxPool( + VARP x, + List kernal, { + PaddingMode pad = PaddingMode.VALID, + List stride = const [1, 1], + List pads = const [0, 0], +}) { + final (kernalPtr, kernalSize) = kernal.toNativeArrayI32(); + final (stridePtr, strideSize) = stride.toNativeArrayI32(); + final (padPtr, padSize) = pads.toNativeArrayI32(); + final rval = VARP.fromPointer( + C.mnn_expr_MaxPool( + x.ptr, + kernalPtr.cast(), + kernalSize, + stridePtr.cast(), + strideSize, + pad.value, + padPtr.cast(), + padSize, + ), + ); + calloc.free(kernalPtr); + calloc.free(stridePtr); + calloc.free(padPtr); + return rval; +} + +VARP avgPool( + VARP x, + List kernal, { + PaddingMode pad = PaddingMode.VALID, + List stride = const [1, 1], + List pads = const [0, 0], +}) { + final (kernalPtr, kernalSize) = kernal.toNativeArrayI32(); + final (stridePtr, strideSize) = stride.toNativeArrayI32(); + final (padPtr, padSize) = pads.toNativeArrayI32(); + final rval = VARP.fromPointer( + C.mnn_expr_AvePool( + x.ptr, + kernalPtr.cast(), + kernalSize, + stridePtr.cast(), + strideSize, + pad.value, + padPtr.cast(), + padSize, + ), + ); + calloc.free(kernalPtr); + calloc.free(stridePtr); + calloc.free(padPtr); + return rval; +} + +VARP reshape(VARP x, List shape, {DimensionFormat format = DimensionFormat.NCHW}) { + final (shapePtr, shapeSize) = shape.toNativeArrayI32(); + final rval = VARP.fromPointer( + C.mnn_expr_Reshape( + x.ptr, + shapePtr.cast(), + shapeSize, + format.value, + ), + ); + calloc.free(shapePtr); + return rval; +} + +VARP scale(VARP x, int channels, List scales, List biases) { + final (scalesPtr, scalesSize) = scales.toNativeArrayF32(); + final (biasesPtr, biasesSize) = biases.toNativeArrayF32(); + final rval = VARP.fromPointer( + C.mnn_expr_Scale( + x.ptr, + channels, + scalesPtr.cast(), + scalesSize, + biasesPtr.cast(), + biasesSize, + ), + ); + calloc.free(scalesPtr); + calloc.free(biasesPtr); + return rval; +} + +VARP ReLU(VARP x, {double slope = 0.0}) => VARP.fromPointer(C.mnn_expr_Relu(x.ptr, slope)); +VARP ReLU6(VARP x, {double slope = 0.0, double maxValue = 6.0}) => + VARP.fromPointer(C.mnn_expr_Relu6(x.ptr, slope, maxValue)); +VARP PReLU(VARP x, List slopes) { + final (slopesPtr, slopesSize) = slopes.toNativeArrayF32(); + final rval = VARP.fromPointer(C.mnn_expr_PRelu(x.ptr, slopesPtr.cast(), slopesSize)); + calloc.free(slopesPtr); + return rval; +} + +VARP softMax(VARP logits, {int axis = -1}) => VARP.fromPointer(C.mnn_expr_Softmax(logits.ptr, axis)); +VARP softPlus(VARP features) => VARP.fromPointer(C.mnn_expr_Softplus(features.ptr)); +VARP softSign(VARP features) => VARP.fromPointer(C.mnn_expr_Softsign(features.ptr)); +List split(VARP value, List sizeSplits, {int axis = 0}) { + final (sizeSplitsPtr, sizeSplitsSize) = sizeSplits.toNativeArrayI32(); + final p = C.mnn_expr_Split(value.ptr, sizeSplitsPtr.cast(), sizeSplitsSize, axis); + final size = C.mnn_expr_VecVARP_size(p); + calloc.free(sizeSplitsPtr); + final rval = List.generate(size, (index) => VARP.fromPointer(C.mnn_expr_VecVARP_at(p, index))); + // only free the struct, keep internal ref.ptr since they are attached + // and will be managed by VARP object + C.mnn_expr_VecVARP_free(p); + return rval; +} + +VARP slice(VARP x, VARP starts, VARP sizes) => + VARP.fromPointer(C.mnn_expr_Slice(x.ptr, starts.ptr, sizes.ptr)); +VARP stridedSlice( + VARP input, + VARP begin, + VARP end, + VARP strided, + int beginMask, + int endMask, + int ellipsisMask, + int newAxisMask, + int shrinkAxisMask, +) => + VARP.fromPointer( + C.mnn_expr_StridedSlice( + input.ptr, + begin.ptr, + end.ptr, + strided.ptr, + beginMask, + endMask, + ellipsisMask, + newAxisMask, + shrinkAxisMask, + ), + ); +VARP stridedSliceWrite( + VARP input, + VARP begin, + VARP end, + VARP strided, + VARP write, + int beginMask, + int endMask, + int ellipsisMask, + int newAxisMask, + int shrinkAxisMask, +) => + VARP.fromPointer( + C.mnn_expr_StridedSliceWrite( + input.ptr, + begin.ptr, + end.ptr, + strided.ptr, + write.ptr, + beginMask, + endMask, + ellipsisMask, + newAxisMask, + shrinkAxisMask, + ), + ); + +VARP concat(List values, int axis) { + final pVec = values.toNativeVec(); + final rval = VARP.fromPointer(C.mnn_expr_Concat(pVec.ptr, axis)); + pVec.dispose(); + return rval; +} + +VARP convert(VARP input, DimensionFormat format) => + VARP.fromPointer(C.mnn_expr_Convert(input.ptr, format.value)); + +VARP transpose(VARP x, List perm) { + final (permPtr, permSize) = perm.toNativeArrayI32(); + final rval = VARP.fromPointer(C.mnn_expr_Transpose(x.ptr, permPtr.cast(), permSize)); + calloc.free(permPtr); + return rval; +} + +VARP transpose1(VARP x, VARP perm) { + final rval = VARP.fromPointer(C.mnn_expr_Transpose_1(x.ptr, perm.ptr)); + return rval; +} + +VARP channelShuffle(VARP x, int group) => VARP.fromPointer(C.mnn_expr_ChannelShuffle(x.ptr, group)); +VARP changeInputFormat(VARP x, DimensionFormat format) => + VARP.fromPointer(C.mnn_expr_ChangeInputFormat(x.ptr, format.value)); + +VARP reverse(VARP x, VARP axis) => VARP.fromPointer(C.mnn_expr_Reverse(x.ptr, axis.ptr)); +VARP reverseSequence(VARP x, VARP y, int batchDim, int seqDim) => + VARP.fromPointer(C.mnn_expr_ReverseSequence(x.ptr, y.ptr, batchDim, seqDim)); +VARP crop(VARP images, VARP size, int axis, List offset) { + final (offsetPtr, offsetSize) = offset.toNativeArrayI32(); + final rval = VARP.fromPointer(C.mnn_expr_Crop(images.ptr, size.ptr, axis, offsetPtr.cast(), offsetSize)); + calloc.free(offsetPtr); + return rval; +} + +VARP resize(VARP images, double xScale, double yScale) => + VARP.fromPointer(C.mnn_expr_Resize(images.ptr, xScale, yScale)); + +VARP pad(VARP x, VARP paddings, {PadValueMode mode = PadValueMode.CONSTANT}) => + VARP.fromPointer(C.mnn_expr_Pad(x.ptr, paddings.ptr, mode.value)); + +VARP expandDims(VARP x, int axis) => VARP.fromPointer(C.mnn_expr_ExpandDims(x.ptr, axis)); +VARP expandDims1(VARP x, VARP axis) => VARP.fromPointer(C.mnn_expr_ExpandDims_1(x.ptr, axis.ptr)); + +VARP shape(VARP input, {bool nchw = false}) => VARP.fromPointer(C.mnn_expr_Shape(input.ptr, nchw)); + +VARP stack(List values, {int axis = 0}) { + final pVec = values.toNativeVec(); + final rval = VARP.fromPointer(C.mnn_expr_Stack(pVec.ptr, axis)); + pVec.dispose(); + return rval; +} + +VARP cropAndResize( + VARP image, + VARP boxes, + VARP boxInd, + VARP cropSize, + InterpolationMethod method, { + double extrapolationValue = 0.0, +}) => + VARP.fromPointer( + C.mnn_expr_CropAndResize( + image.ptr, + boxes.ptr, + boxInd.ptr, + cropSize.ptr, + method.value, + extrapolationValue, + ), + ); + +VARP fill(VARP dims, VARP value) => VARP.fromPointer(C.mnn_expr_Fill(dims.ptr, value.ptr)); +VARP tile(VARP input, VARP multiples) => VARP.fromPointer(C.mnn_expr_Tile(input.ptr, multiples.ptr)); +VARP gather(VARP input, VARP indices) => VARP.fromPointer(C.mnn_expr_Gather(input.ptr, indices.ptr)); +VARP squeeze(VARP input, {List axis = const []}) { + final (axisPtr, axisSize) = axis.toNativeArrayI32(); + final rval = VARP.fromPointer(C.mnn_expr_Squeeze(input.ptr, axisPtr.cast(), axisSize)); + calloc.free(axisPtr); + return rval; +} + +VARP batchToSpaceND(VARP input, VARP blockShape, VARP crops) => + VARP.fromPointer(C.mnn_expr_BatchToSpaceND(input.ptr, crops.ptr, blockShape.ptr)); +VARP gatherND(VARP params, VARP indices) => VARP.fromPointer(C.mnn_expr_GatherND(params.ptr, indices.ptr)); +VARP gatherElements(VARP params, VARP indices, {VARP? axis}) => VARP.fromPointer( + axis == null + ? C.mnn_expr_GatherElements(params.ptr, indices.ptr) + : C.mnn_expr_GatherElements_1(params.ptr, indices.ptr, axis.ptr), + ); +VARP selu(VARP features, double scale, double alpha) => + VARP.fromPointer(C.mnn_expr_Selu(features.ptr, scale, alpha)); +VARP size(VARP input) => VARP.fromPointer(C.mnn_expr_Size(input.ptr)); +VARP elu(VARP features, {double alpha = 1.0}) => VARP.fromPointer(C.mnn_expr_Elu(features.ptr, alpha)); +VARP threshold(VARP features, {double alpha = 1.0}) => + VARP.fromPointer(C.mnn_expr_Threshold(features.ptr, alpha)); +VARP matrixBandPart(VARP input, VARP lower, VARP upper) => + VARP.fromPointer(C.mnn_expr_MatrixBandPart(input.ptr, lower.ptr, upper.ptr)); +List moments(VARP x, List axis, VARP shift, bool keepDims) { + final (axisPtr, axisSize) = axis.toNativeArrayI32(); + final vec = VecVARP.fromPointer(C.mnn_expr_Moments(x.ptr, axisPtr.cast(), axisSize, shift.ptr, keepDims)); + calloc.free(axisPtr); + final rval = vec.toList(); + vec.dispose(); + return rval; +} + +VARP setDiff1D(VARP x, VARP y) => VARP.fromPointer(C.mnn_expr_SetDiff1D(x.ptr, y.ptr)); +VARP spaceToDepth(VARP input, int blockSize) => + VARP.fromPointer(C.mnn_expr_SpaceToDepth(input.ptr, blockSize)); +VARP spaceToBatchND(VARP input, VARP blockShape, VARP paddings) => + VARP.fromPointer(C.mnn_expr_SpaceToBatchND(input.ptr, blockShape.ptr, paddings.ptr)); +VARP zerosLike(VARP input) => VARP.fromPointer(C.mnn_expr_ZerosLike(input.ptr)); +List unstack(VARP input, {int axis = 0}) { + final vec = VecVARP.fromPointer(C.mnn_expr_Unstack(input.ptr, axis)); + final rval = vec.toList(); + vec.dispose(); + return rval; +} + +VARP rank(VARP input) => VARP.fromPointer(C.mnn_expr_Rank(input.ptr)); +VARP range(VARP start, VARP limit, VARP delta) => + VARP.fromPointer(C.mnn_expr_Range(start.ptr, limit.ptr, delta.ptr)); +VARP depthToSpace(VARP input, int blockSize) => + VARP.fromPointer(C.mnn_expr_DepthToSpace(input.ptr, blockSize)); +VARP Permute(VARP input, List dims) { + final (permPtr, permSize) = dims.toNativeArrayI32(); + final rval = VARP.fromPointer(C.mnn_expr_Permute(input.ptr, permPtr.cast(), permSize)); + calloc.free(permPtr); + return rval; +} + +VARP interp( + List xs, + double widthScale, + double heightScale, + int outputWidth, + int outputHeight, + int resizeType, + bool alignCorners, +) { + final xsPtr = xs.toNativeVec(); + final rval = VARP.fromPointer( + C.mnn_expr_Interp( + xsPtr.ptr, + widthScale, + heightScale, + outputWidth, + outputHeight, + resizeType, + alignCorners, + ), + ); + xsPtr.dispose(); + return rval; +} + +VARP zeroGrad(VARP input) => VARP.fromPointer(C.mnn_expr_ZeroGrad(input.ptr)); + +VARP CosineSimilarity(VARP input0, VARP input1, VARP inputDim) => + VARP.fromPointer(C.mnn_expr_CosineSimilarity(input0.ptr, input1.ptr, inputDim.ptr)); + +VARP GridSample( + VARP input, + VARP grid, { + InterpolationMethod mode = InterpolationMethod.BILINEAR, + GridSamplePaddingMode paddingMode = GridSamplePaddingMode.GRID_SAMPLE_PADDING_ZEROS, + bool alignCorners = false, +}) => + VARP.fromPointer(C.mnn_expr_GridSample(input.ptr, grid.ptr, mode.value, paddingMode.value, alignCorners)); + +VARP floatToInt8(VARP x, VARP scale, int minvalue, int maxValue, {int? zeroPoint}) => VARP.fromPointer( + zeroPoint == null + ? C.mnn_expr_FloatToInt8(x.ptr, scale.ptr, minvalue, maxValue) + : C.mnn_expr_FloatToInt8_1(x.ptr, scale.ptr, minvalue, maxValue, zeroPoint), + ); + +VARP int8ToFloat(VARP x, VARP scale, {int? zeroPoint}) => VARP.fromPointer( + zeroPoint == null + ? C.mnn_expr_Int8ToFloat(x.ptr, scale.ptr) + : C.mnn_expr_Int8ToFloat_1(x.ptr, scale.ptr, zeroPoint), + ); + +VARP select(VARP select, VARP input0, VARP input1) => + VARP.fromPointer(C.mnn_expr_Select(select.ptr, input0.ptr, input1.ptr)); + +VARP where(VARP x) => VARP.fromPointer(C.mnn_expr_Where(x.ptr)); + +VARP sort(VARP x, {int axis = -1, bool arg = false, bool descend = false}) => + VARP.fromPointer(C.mnn_expr_Sort(x.ptr, axis, arg, descend)); diff --git a/lib/src/expr/utils.dart b/lib/src/expr/utils.dart new file mode 100644 index 0000000..3473d4d --- /dev/null +++ b/lib/src/expr/utils.dart @@ -0,0 +1,79 @@ +import 'dart:ffi' as ffi; + +import 'package:ffi/ffi.dart'; + +extension ListIntExtension on List { + (ffi.Pointer ptr, int size) toNativeArrayI8({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayU8({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayI16({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayU16({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayU32({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayI32({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayU64({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayI64({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayF32({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, map((e) => e.toDouble())); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayF64({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, map((e) => e.toDouble())); + return (ptr, length); + } +} + +extension ListDoubleExtension on List { + (ffi.Pointer ptr, int size) toNativeArrayF32({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } + + (ffi.Pointer ptr, int size) toNativeArrayF64({ffi.Pointer? ptr}) { + ptr ??= calloc.allocate(length); + ptr.asTypedList(length).setAll(0, this); + return (ptr, length); + } +} diff --git a/lib/src/formatter.dart b/lib/src/formatter.dart new file mode 100644 index 0000000..8fb0ee5 --- /dev/null +++ b/lib/src/formatter.dart @@ -0,0 +1,158 @@ +/// Copyright (c) 2025, rainyl. All rights reserved. +/// Use of this source code is governed by a +/// Apache 2.0 license that can be found in the LICENSE file. + +import 'dart:math'; +import 'package:mnn/src/expr/expr.dart'; + +class PrintOptions { + final int precision; + final int threshold; + final int edgeitems; + final int linewidth; + final bool suppress; + const PrintOptions({ + this.precision = 6, + this.threshold = 1000, + this.edgeitems = 3, + this.linewidth = 75, + this.suppress = false, + }); +} + +String formatFloat(num x, int precision, bool suppress) { + if (suppress && x.abs() < pow(10, -precision)) { + return x.sign < 0 ? '-0.${'0' * precision}' : '0.${'0' * precision}'; + } + return x.toStringAsFixed(precision); +} + +String formatInt(int x) => x.toString(); + +List calcColumnWidths(List data, List shape, PrintOptions options) { + if (shape.length < 2) return []; + final int rows = shape[0], cols = shape[1]; + final List widths = List.filled(cols, 0); + final int stride = cols; + for (int c = 0; c < cols; ++c) { + int maxw = 0; + for (int r = 0; r < rows; ++r) { + final int idx = r * stride + c; + if (idx >= data.length) break; + final v = data[idx]; + String s; + if (v is int || (v is double && v == v.roundToDouble())) { + s = formatInt(v.toInt()); + } else { + s = formatFloat(v, options.precision, options.suppress); + } + maxw = max(maxw, s.length); + } + widths[c] = maxw; + } + return widths; +} + +String formatAligned(num v, int width, PrintOptions options) { + String s; + if (v is int || (v is double && v == v.roundToDouble())) { + s = formatInt(v.toInt()); + } else { + s = formatFloat(v, options.precision, options.suppress); + } + return s.padLeft(width, ' '); +} + +String array2string( + List data, + List shape, { + PrintOptions options = const PrintOptions(), + String separator = ' ', + String prefix = '', + String suffix = '', +}) { + final int size = shape.isEmpty ? 0 : shape.reduce((a, b) => a * b); + final bool summarised = size > options.threshold; + final edge = options.edgeitems; + + final List colWidths = shape.length == 2 ? calcColumnWidths(data, shape, options) : []; + + String formatArray(int index, int dim) { + if (dim == shape.length) { + final v = data[index]; + if (colWidths.isNotEmpty && shape.length == 2) { + final int stride = shape[1]; + final int col = index % stride; + return formatAligned(v, colWidths[col], options); + } + if (v is int) return formatInt(v); + if (v is double) { + if (v is int || (v == v.roundToDouble())) { + return v.toInt().toString(); + } + return formatFloat(v, options.precision, options.suppress); + } + return v.toString(); + } + + final int curDim = shape[dim]; + int stride = 1; + for (int i = dim + 1; i < shape.length; ++i) { + stride *= shape[i]; + } + + final List items = []; + if (summarised && curDim > 2 * edge) { + for (int i = 0; i < edge; ++i) { + items.add(formatArray(index + i * stride, dim + 1)); + } + items.add('...'); + for (int i = curDim - edge; i < curDim; ++i) { + items.add(formatArray(index + i * stride, dim + 1)); + } + } else { + for (int i = 0; i < curDim; ++i) { + items.add(formatArray(index + i * stride, dim + 1)); + } + } + String sep; + if (dim == shape.length - 1) { + sep = separator; + } else if (shape.length == 2 && dim == 0) { + sep = ',\n '; + } else { + sep = ',\n${' ' * (prefix.length + dim + 1)}'; + } + return '[${items.join(sep)}]'; + } + + if (size == 0) return '[]'; + + String arrayStr = formatArray(0, 0); + + if (summarised && shape.isNotEmpty) { + arrayStr += ', shape=$shape'; + } + return prefix + arrayStr + suffix; +} + +/// Extension methods for VARP formatting +extension VARPFormatting on VARP { + /// Convert VARP to formatted string + String formatString([PrintOptions? options]) { + return array2string( + data, + dim, + options: options ?? const PrintOptions(), + prefix: 'VARP(', + suffix: ', dtype=$dtype)', + ); + } + + /// Pretty print VARP to console + void print_([PrintOptions? options]) { + final str = formatString(options); + // ignore: avoid_print + print(str); + } +} diff --git a/lib/src/g/mnn.g.dart b/lib/src/g/mnn.g.dart index c9bd150..325c88b 100644 --- a/lib/src/g/mnn.g.dart +++ b/lib/src/g/mnn.g.dart @@ -555,2065 +555,4794 @@ external void mnn_cv_matrix_set_translate( double dy, ); -/// @brief Get MNN version -/// @return Version string -@ffi.Native Function()>() -external ffi.Pointer mnn_get_version(); +@ffi.Native() +external VARP_t mnn_expr_Abs( + VARP_t x, +); -/// @brief Get biz code from interpreter -/// @param self Interpreter instance -/// @return Biz code string or NULL if failed -@ffi.Native Function(mnn_interpreter_t)>(isLeaf: true) -external ffi.Pointer mnn_interpreter_biz_code( - mnn_interpreter_t self, +@ffi.Native() +external VARP_t mnn_expr_Acos( + VARP_t x, ); -/// @brief Create interpreter from buffer -/// @param buffer Model data buffer -/// @param size Buffer size -/// @param callback Callback function to be called after creation -/// @return Interpreter instance or NULL if failed -@ffi.Native< - mnn_interpreter_t Function( - ffi.Pointer, ffi.Size, mnn_callback_0)>() -external mnn_interpreter_t mnn_interpreter_create_from_buffer( - ffi.Pointer buffer, - int size, - mnn_callback_0 callback, +@ffi.Native() +external VARP_t mnn_expr_Acosh( + VARP_t x, ); -/// @brief Create interpreter from file -/// @param file_path Path to model file -/// @param callback Callback function to be called after creation -/// @return Interpreter instance or NULL if failed -@ffi.Native, mnn_callback_0)>() -external mnn_interpreter_t mnn_interpreter_create_from_file( - ffi.Pointer file_path, - mnn_callback_0 callback, +/// Math Op +/// BinaryOPs +@ffi.Native() +external VARP_t mnn_expr_Add( + VARP_t x, + VARP_t y, ); -/// @brief Create runtime info -/// @param configs Schedule config array -/// @param count Config count -/// @return Runtime info instance -@ffi.Native< - mnn_runtime_info_t Function(ffi.Pointer, ffi.Size)>() -external mnn_runtime_info_t mnn_interpreter_create_runtime( - ffi.Pointer configs, - int count, +@ffi.Native() +external VARP_t mnn_expr_ArgMax( + VARP_t input, + int axis, ); -/// @brief Create session with config -/// @param self Interpreter instance -/// @param config Schedule config -/// @param callback Callback function to be called after creation -/// @return Session instance or NULL if failed -@ffi.Native< - mnn_session_t Function(mnn_interpreter_t, - ffi.Pointer, mnn_callback_0)>() -external mnn_session_t mnn_interpreter_create_session( - mnn_interpreter_t self, - ffi.Pointer config, - mnn_callback_0 callback, +@ffi.Native() +external VARP_t mnn_expr_ArgMin( + VARP_t input, + int axis, ); -/// @brief Create session with runtime info -/// @param self Interpreter instance -/// @param config Schedule config -/// @param runtime Runtime info -/// @param callback Callback function to be called after creation -/// @return Session instance or NULL if failed -@ffi.Native< - mnn_session_t Function( - mnn_interpreter_t, - ffi.Pointer, - mnn_runtime_info_t, - mnn_callback_0)>() -external mnn_session_t mnn_interpreter_create_session_with_runtime( - mnn_interpreter_t self, - ffi.Pointer config, - mnn_runtime_info_t runtime, - mnn_callback_0 callback, +@ffi.Native() +external VARP_t mnn_expr_Asin( + VARP_t x, ); -/// @brief Destroy interpreter instance -/// @param self Interpreter to destroy -@ffi.Native() -external void mnn_interpreter_destroy( - mnn_interpreter_t self, +@ffi.Native() +external VARP_t mnn_expr_Asinh( + VARP_t x, ); -/// @brief Get backend type -/// @param self Interpreter instance -/// @param session Session -/// @return Backend type -@ffi.Native< - mnn_backend_t Function(mnn_interpreter_t, mnn_session_t, mnn_tensor_t)>() -external mnn_backend_t mnn_interpreter_get_backend( - mnn_interpreter_t self, - mnn_session_t session, - mnn_tensor_t tensor, +@ffi.Native() +external VARP_t mnn_expr_Atan( + VARP_t x, ); -/// @brief Get model buffer -/// @param self Interpreter instance -/// @param buffer Output parameter to receive pointer to model data -/// @return Size of model data in bytes, or 0 if failed -@ffi.Native< - ffi.Size Function(mnn_interpreter_t, ffi.Pointer>)>() -external int mnn_interpreter_get_model_buffer( - mnn_interpreter_t self, - ffi.Pointer> buffer, +@ffi.Native() +external VARP_t mnn_expr_Atan2( + VARP_t x, + VARP_t y, ); -/// @brief Get model version -/// @param self Interpreter instance -/// @return Version string or NULL if failed -@ffi.Native Function(mnn_interpreter_t)>(isLeaf: true) -external ffi.Pointer mnn_interpreter_get_model_version( - mnn_interpreter_t self, +@ffi.Native() +external VARP_t mnn_expr_Atanh( + VARP_t x, ); -/// @brief Get session info -/// @param self Interpreter instance -/// @param session Session -/// @param info Output parameter for session info -/// @return Error code @ffi.Native< - ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, ffi.Int, - ffi.Pointer)>(symbol: 'mnn_interpreter_get_session_info') -external int _mnn_interpreter_get_session_info( - mnn_interpreter_t self, - mnn_session_t session, - int session_info_code, - ffi.Pointer info, + VARP_t Function( + VARP_t, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size, + ffi.Int, + ffi.Pointer, + ffi.Size)>() +external VARP_t mnn_expr_AvePool( + VARP_t x, + ffi.Pointer kernel, + int kernelLength, + ffi.Pointer stride, + int strideLength, + int pad, + ffi.Pointer pads, + int padsLength, ); -ErrorCode mnn_interpreter_get_session_info( - mnn_interpreter_t self, - mnn_session_t session, - int session_info_code, - ffi.Pointer info, -) => - ErrorCode.fromValue(_mnn_interpreter_get_session_info( - self, - session, - session_info_code, - info, - )); +@ffi.Native() +external VARP_t mnn_expr_BatchMatMul( + VARP_t x, + VARP_t y, + bool adj_x, + bool adj_y, +); + +@ffi.Native() +external VARP_t mnn_expr_BatchToSpaceND( + VARP_t input, + VARP_t block_shape, + VARP_t crops, +); + +@ffi.Native() +external VARP_t mnn_expr_BiasAdd( + VARP_t value, + VARP_t bias, +); + +@ffi.Native() +external VARP_t mnn_expr_BitwiseAnd( + VARP_t x, + VARP_t y, +); + +@ffi.Native() +external VARP_t mnn_expr_BitwiseOr( + VARP_t x, + VARP_t y, +); + +@ffi.Native() +external VARP_t mnn_expr_BitwiseXor( + VARP_t x, + VARP_t y, +); + +@ffi.Native() +external VARP_t mnn_expr_BroadcastTo( + VARP_t a, + VARP_t shape, +); + +/// OtherOPs +/// template +/// VARP _Cast(VARP x) { +/// return _Cast(x, halide_type_of()); +/// } +@ffi.Native() +external VARP_t mnn_expr_Cast( + VARP_t x, + halide_type_c_t dtype, +); + +@ffi.Native() +external VARP_t mnn_expr_Ceil( + VARP_t x, +); + +@ffi.Native() +external VARP_t mnn_expr_ChangeInputFormat( + VARP_t input, + int format, +); + +@ffi.Native() +external VARP_t mnn_expr_ChannelShuffle( + VARP_t x, + int group, +); + +@ffi.Native() +external VARP_t mnn_expr_Clone( + VARP_t source, + bool deepCopy, +); -/// @brief Get input tensor by name -/// @param self Interpreter instance -/// @param session Session -/// @param name Tensor name (NULL for first input) -/// @return Tensor instance or NULL if failed @ffi.Native< - mnn_tensor_t Function( - mnn_interpreter_t, mnn_session_t, ffi.Pointer)>() -external mnn_tensor_t mnn_interpreter_get_session_input( - mnn_interpreter_t self, - mnn_session_t session, - ffi.Pointer name, + VARP_t Function( + VARP_t, + VARP_t, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size)>() +external VARP_t mnn_expr_Col2Im( + VARP_t x, + VARP_t outputShape, + ffi.Pointer kernelSize, + int kernelSizeLength, + ffi.Pointer dilate, + int dilateLength, + ffi.Pointer pads, + int padsLength, + ffi.Pointer stride, + int strideLength, +); + +@ffi.Native() +external VARP_t mnn_expr_Concat( + VecVARP_t values, + int axis, ); -/// @brief Get all input tensors from session -/// @param self Interpreter instance -/// @param session Session -/// @param tensors Output parameter for tensor array -/// @param count Output parameter for tensor count -/// @return Error code @ffi.Native< - ffi.UnsignedInt Function( - mnn_interpreter_t, - mnn_session_t, - ffi.Pointer>, - ffi.Pointer>>, - ffi.Pointer)>(symbol: 'mnn_interpreter_get_session_input_all') -external int _mnn_interpreter_get_session_input_all( - mnn_interpreter_t self, - mnn_session_t session, - ffi.Pointer> tensors, - ffi.Pointer>> names, - ffi.Pointer count, + VARP_t Function(ffi.Pointer, ffi.Pointer, ffi.Size, + ffi.Int, halide_type_c_t)>() +external VARP_t mnn_expr_Const( + ffi.Pointer value, + ffi.Pointer shape, + int shapeLength, + int format, + halide_type_c_t type, ); -ErrorCode mnn_interpreter_get_session_input_all( - mnn_interpreter_t self, - mnn_session_t session, - ffi.Pointer> tensors, - ffi.Pointer>> names, - ffi.Pointer count, -) => - ErrorCode.fromValue(_mnn_interpreter_get_session_input_all( - self, - session, - tensors, - names, - count, - )); +/// MNN_PUBLIC VARP _InnerProduct(std::vector&& weight, std::vector&& bias, VARP x, +/// INTS outputShape); +@ffi.Native< + VARP_t Function( + VARP_t, + VARP_t, + VARP_t, + ffi.Int, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size, + ffi.Int, + ffi.Pointer, + ffi.Size)>() +external VARP_t mnn_expr_Conv( + VARP_t weight, + VARP_t bias, + VARP_t x, + int pad, + ffi.Pointer stride, + int strideLength, + ffi.Pointer dilate, + int dilateLength, + int group, + ffi.Pointer pads, + int padsLength, +); + +@ffi.Native() +external VARP_t mnn_expr_Convert( + VARP_t input, + int format, +); + +@ffi.Native() +external VARP_t mnn_expr_Cos( + VARP_t x, +); + +@ffi.Native() +external VARP_t mnn_expr_Cosh( + VARP_t x, +); + +/// Int8 Inference +/// MNN_PUBLIC VARP _Conv(std::vector&& weight, std::vector&& bias, std::vector&& +/// scale, VARP x, INTS channel, INTS kernelSize, +/// PaddingMode pad, INTS stride, INTS dilate, int group, INTS pads, bool relu, +/// int nbits = 8); +/// MNN_PUBLIC VARP _Conv(std::vector&& weight, std::vector&& bias, std::vector&& +/// scale, +/// VARP x, INTS channel, INTS kernelSize, +/// PaddingMode pad, INTS stride, INTS dilate, int group, INTS pads, bool relu, +/// int8_t inputZeroPoint, int8_t outputZeroPoint, +/// int8_t minValue, int8_t maxValue, bool accumulateToInt16); +/// MNN_PUBLIC VARP _Conv(std::vector&& weight, std::vector&& bias, +/// std::vector&& weightScale, +/// VARP x, INTS channel, INTS kernelSize, +/// PaddingMode pad, INTS stride, INTS dilate, int group, INTS pads, bool relu, +/// float scaleIn, float scaleOut, +/// int8_t inputZeroPoint, int8_t outputZeroPoint, +/// int8_t minValue, int8_t maxValue, float weightClampValue, bool +/// accumulateToInt16); +@ffi.Native() +external VARP_t mnn_expr_CosineSimilarity( + VARP_t input0, + VARP_t input1, + VARP_t inputDim, +); -/// @brief Get output tensor by name -/// @param self Interpreter instance -/// @param session Session -/// @param name Tensor name (NULL for first output) -/// @return Tensor instance or NULL if failed @ffi.Native< - mnn_tensor_t Function( - mnn_interpreter_t, mnn_session_t, ffi.Pointer)>() -external mnn_tensor_t mnn_interpreter_get_session_output( - mnn_interpreter_t self, - mnn_session_t session, - ffi.Pointer name, + VARP_t Function(VARP_t, VARP_t, ffi.Int, ffi.Pointer, ffi.Size)>() +external VARP_t mnn_expr_Crop( + VARP_t images, + VARP_t size, + int axis, + ffi.Pointer offset, + int offsetLength, ); -/// @brief Get all output tensors from session -/// @param self Interpreter instance -/// @param session Session -/// @param tensors Output parameter for tensor array -/// @param count Output parameter for tensor count -/// @return Error code +/// enum InterpolationMethod {BILINEAR, NEAREST}; @ffi.Native< - ffi.UnsignedInt Function( - mnn_interpreter_t, - mnn_session_t, - ffi.Pointer>, - ffi.Pointer>>, - ffi.Pointer)>( - symbol: 'mnn_interpreter_get_session_output_all') -external int _mnn_interpreter_get_session_output_all( - mnn_interpreter_t self, - mnn_session_t session, - ffi.Pointer> tensors, - ffi.Pointer>> names, - ffi.Pointer count, + VARP_t Function(VARP_t, VARP_t, VARP_t, VARP_t, ffi.Int, ffi.Float)>() +external VARP_t mnn_expr_CropAndResize( + VARP_t image, + VARP_t boxes, + VARP_t box_ind, + VARP_t crop_size, + int method, + double extrapolation_value, ); -ErrorCode mnn_interpreter_get_session_output_all( - mnn_interpreter_t self, - mnn_session_t session, - ffi.Pointer> tensors, - ffi.Pointer>> names, - ffi.Pointer count, -) => - ErrorCode.fromValue(_mnn_interpreter_get_session_output_all( - self, - session, - tensors, - names, - count, - )); +@ffi.Native() +external VARP_t mnn_expr_CumProd( + VARP_t x, + int axis, +); -/// @brief Release model -/// @param self Interpreter instance -@ffi.Native() -external void mnn_interpreter_release_model( - mnn_interpreter_t self, +@ffi.Native() +external VARP_t mnn_expr_CumSum( + VARP_t x, + int axis, + bool exclusive, + bool reverse, ); -/// @brief Release session -/// @param self Interpreter instance -/// @param session Session to release -/// @param callback Callback function to be called after release -/// @return Error code @ffi.Native< - ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, - mnn_callback_0)>(symbol: 'mnn_interpreter_release_session') -external int _mnn_interpreter_release_session( - mnn_interpreter_t self, - mnn_session_t session, - mnn_callback_0 callback, + VARP_t Function( + VARP_t, + VARP_t, + VARP_t, + ffi.Int, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size, + ffi.Int, + ffi.Pointer, + ffi.Size)>() +external VARP_t mnn_expr_Deconv( + VARP_t weight, + VARP_t bias, + VARP_t x, + int pad, + ffi.Pointer stride, + int strideLength, + ffi.Pointer dilate, + int dilateLength, + int group, + ffi.Pointer pads, + int padsLength, ); -ErrorCode mnn_interpreter_release_session( - mnn_interpreter_t self, - mnn_session_t session, - mnn_callback_0 callback, -) => - ErrorCode.fromValue(_mnn_interpreter_release_session( - self, - session, - callback, - )); +@ffi.Native() +external VARP_t mnn_expr_DepthToSpace( + VARP_t input, + int block_size, +); -/// @brief Resize session -/// @param self Interpreter instance -/// @param session Session to resize -/// @param callback Callback function to be called after resize -/// @return Error code -@ffi.Native< - ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, - mnn_callback_0)>(symbol: 'mnn_interpreter_resize_session') -external int _mnn_interpreter_resize_session( - mnn_interpreter_t self, - mnn_session_t session, - mnn_callback_0 callback, +@ffi.Native() +external VARP_t mnn_expr_Divide( + VARP_t x, + VARP_t y, ); -ErrorCode mnn_interpreter_resize_session( - mnn_interpreter_t self, - mnn_session_t session, - mnn_callback_0 callback, -) => - ErrorCode.fromValue(_mnn_interpreter_resize_session( - self, - session, - callback, - )); +@ffi.Native() +external VARP_t mnn_expr_Elu( + VARP_t features, + double alpha, +); -/// @brief Resize tensor -/// @param tensor Tensor to resize -/// @param dims New dimensions array -/// @param dim_count Dimension count -/// @return Error code -@ffi.Native< - ffi.UnsignedInt Function(mnn_interpreter_t, mnn_tensor_t, - ffi.Pointer, ffi.Int)>(symbol: 'mnn_interpreter_resize_tensor') -external int _mnn_interpreter_resize_tensor( - mnn_interpreter_t self, - mnn_tensor_t tensor, - ffi.Pointer dims, - int dim_count, +@ffi.Native() +external VARP_t mnn_expr_Equal( + VARP_t x, + VARP_t y, ); -ErrorCode mnn_interpreter_resize_tensor( - mnn_interpreter_t self, - mnn_tensor_t tensor, - ffi.Pointer dims, - int dim_count, -) => - ErrorCode.fromValue(_mnn_interpreter_resize_tensor( - self, - tensor, - dims, - dim_count, - )); +@ffi.Native() +external VARP_t mnn_expr_Erf( + VARP_t x, +); -@ffi.Native< - ffi.UnsignedInt Function(mnn_interpreter_t, mnn_tensor_t, ffi.Int, ffi.Int, - ffi.Int, ffi.Int)>(symbol: 'mnn_interpreter_resize_tensor_1') -external int _mnn_interpreter_resize_tensor_1( - mnn_interpreter_t self, - mnn_tensor_t tensor, - int batch, - int channel, - int height, - int width, +@ffi.Native() +external VARP_t mnn_expr_Erfc( + VARP_t x, ); -ErrorCode mnn_interpreter_resize_tensor_1( - mnn_interpreter_t self, - mnn_tensor_t tensor, - int batch, - int channel, - int height, - int width, -) => - ErrorCode.fromValue(_mnn_interpreter_resize_tensor_1( - self, - tensor, - batch, - channel, - height, - width, - )); +@ffi.Native() +external VARP_t mnn_expr_Erfinv( + VARP_t x, +); -/// @brief Run session -/// @param self Interpreter instance -/// @param session Session to run -/// @param callback Callback function to be called after run -/// @return Error code -@ffi.Native< - ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, - mnn_callback_0)>(symbol: 'mnn_interpreter_run_session') -external int _mnn_interpreter_run_session( - mnn_interpreter_t self, - mnn_session_t session, - mnn_callback_0 callback, +@ffi.Native() +external VARP_t mnn_expr_Exp( + VARP_t x, ); -ErrorCode mnn_interpreter_run_session( - mnn_interpreter_t self, - mnn_session_t session, - mnn_callback_0 callback, -) => - ErrorCode.fromValue(_mnn_interpreter_run_session( - self, - session, - callback, - )); +@ffi.Native() +external VARP_t mnn_expr_ExpandDims( + VARP_t input, + int axis, +); -/// @brief Set cache file for interpreter -/// @param self Interpreter instance -/// @param cache_file Cache file path -/// @param key_size Key size -@ffi.Native< - ffi.Void Function(mnn_interpreter_t, ffi.Pointer, ffi.Size)>() -external void mnn_interpreter_set_cache_file( - mnn_interpreter_t self, - ffi.Pointer cache_file, - int key_size, +@ffi.Native() +external VARP_t mnn_expr_ExpandDims_1( + VARP_t input, + VARP_t axis, ); -/// @brief Set external file for interpreter -/// @param self Interpreter instance -/// @param file External file path -/// @param flag Flag value -@ffi.Native< - ffi.Void Function(mnn_interpreter_t, ffi.Pointer, ffi.Size)>() -external void mnn_interpreter_set_external_file( - mnn_interpreter_t self, - ffi.Pointer file, - int flag, +@ffi.Native() +external VARP_t mnn_expr_Expm1( + VARP_t x, ); -/// @brief Set session hint -/// @param self Interpreter instance -/// @param mode Hint mode -/// @param value Hint value -@ffi.Native() -external void mnn_interpreter_set_session_hint( - mnn_interpreter_t self, - int mode, - int value, +/// MNN::Express::Expr +@ffi.Native() +external EXPRP_t mnn_expr_Expr_create_empty(); + +@ffi.Native() +external void mnn_expr_Expr_free( + EXPRP_t self, ); -/// @brief Set session mode -/// @param self Interpreter instance -/// @param mode Session mode -@ffi.Native() -external void mnn_interpreter_set_session_mode( - mnn_interpreter_t self, - int mode, +@ffi.Native() +external VecVARP_t mnn_expr_Expr_getInputs( + EXPRP_t self, ); -/// @brief Update cache file -/// @param self Interpreter instance -/// @param session Session -/// @param flag Flag value -/// @return Error code -@ffi.Native< - ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, ffi.Int)>( - symbol: 'mnn_interpreter_update_cache_file') -external int _mnn_interpreter_update_cache_file( - mnn_interpreter_t self, - mnn_session_t session, - int flag, +@ffi.Native Function(EXPRP_t)>() +external ffi.Pointer mnn_expr_Expr_getName( + EXPRP_t self, ); -ErrorCode mnn_interpreter_update_cache_file( - mnn_interpreter_t self, - mnn_session_t session, - int flag, -) => - ErrorCode.fromValue(_mnn_interpreter_update_cache_file( - self, - session, - flag, - )); +@ffi.Native() +external Op_t mnn_expr_Expr_getOp( + EXPRP_t self, +); -/// @brief Update session to model -/// @param self Interpreter instance -/// @param session Session -/// @return Error code -@ffi.Native( - symbol: 'mnn_interpreter_update_session_to_model') -external int _mnn_interpreter_update_session_to_model( - mnn_interpreter_t self, - mnn_session_t session, +@ffi.Native Function(EXPRP_t, ffi.Int)>() +external ffi.Pointer mnn_expr_Expr_getOutputName( + EXPRP_t self, + int index, ); -ErrorCode mnn_interpreter_update_session_to_model( - mnn_interpreter_t self, - mnn_session_t session, -) => - ErrorCode.fromValue(_mnn_interpreter_update_session_to_model( - self, - session, - )); +@ffi.Native() +external int mnn_expr_Expr_getOutputSize( + EXPRP_t self, +); -/// @brief Get uuid from interpreter -/// @param self Interpreter instance -/// @return Uuid string or NULL if failed -@ffi.Native Function(mnn_interpreter_t)>(isLeaf: true) -external ffi.Pointer mnn_interpreter_uuid( - mnn_interpreter_t self, +@ffi.Native() +external VecWeakEXPRP_t mnn_expr_Expr_getOutputs( + EXPRP_t self, ); -/// @brief Destroy runtime info -/// @param runtime Runtime info to destroy -@ffi.Native() -external void mnn_runtime_info_destroy( - mnn_runtime_info_t runtime, +@ffi.Native() +external int mnn_expr_Expr_inputType( + EXPRP_t self, ); -/// @brief Get tensor batch -/// @param self Tensor -/// @return Batch -@ffi.Native(isLeaf: true) -external int mnn_tensor_batch( - mnn_tensor_t self, +/// MNN_C_API void mnn_expr_Expr_visitOutputs(); +@ffi.Native Function(EXPRP_t, ffi.Int)>() +external ffi.Pointer mnn_expr_Expr_outputInfo( + EXPRP_t self, + int index, ); -/// @brief Get buffer -/// @param self Tensor -/// @return Buffer pointer -@ffi.Native Function(mnn_tensor_t)>(isLeaf: true) -external ffi.Pointer mnn_tensor_buffer( - mnn_tensor_t self, +@ffi.Native() +external bool mnn_expr_Expr_requireInfo( + EXPRP_t self, ); -/// @brief Get tensor channel -/// @param self Tensor -/// @return Channel -@ffi.Native(isLeaf: true) -external int mnn_tensor_channel( - mnn_tensor_t self, +@ffi.Native)>() +external void mnn_expr_Expr_setName( + EXPRP_t self, + ffi.Pointer name, ); -/// @brief Clone tensor -/// @param src Source tensor -/// @param deep_copy Whether to perform deep copy -/// @return Cloned tensor or NULL if failed -@ffi.Native() -external mnn_tensor_t mnn_tensor_clone( - mnn_tensor_t src, - bool deep_copy, +@ffi.Native() +external EXPRP_t mnn_expr_Expr_static_create( + mnn_tensor_t tensor, + bool own, ); -/// @brief Copy data from host tensor -/// @param self Target tensor -/// @param host_tensor Source tensor -/// @return Error code -@ffi.Native( - symbol: 'mnn_tensor_copy_from_host') -external int _mnn_tensor_copy_from_host( - mnn_tensor_t self, - mnn_tensor_t host_tensor, +@ffi.Native< + EXPRP_t Function(ffi.Pointer, ffi.Pointer, + ffi.Int, ffi.Int)>() +external EXPRP_t mnn_expr_Expr_static_create_1( + ffi.Pointer info, + ffi.Pointer ptr, + int type, + int memoryType, ); -ErrorCode mnn_tensor_copy_from_host( - mnn_tensor_t self, - mnn_tensor_t host_tensor, -) => - ErrorCode.fromValue(_mnn_tensor_copy_from_host( - self, - host_tensor, - )); +@ffi.Native() +external EXPRP_t mnn_expr_Expr_static_create_2( + OpT_t op, + VecVARP_t inputs, + int outputSize, +); -/// @brief Copy data to host tensor -/// @param self Source tensor -/// @param host_tensor Target tensor -/// @return Error code -@ffi.Native( - symbol: 'mnn_tensor_copy_to_host') -external int _mnn_tensor_copy_to_host( - mnn_tensor_t self, - mnn_tensor_t host_tensor, +@ffi.Native() +external void mnn_expr_Expr_static_replace( + EXPRP_t oldExpr, + EXPRP_t newExpr, ); -ErrorCode mnn_tensor_copy_to_host( - mnn_tensor_t self, - mnn_tensor_t host_tensor, -) => - ErrorCode.fromValue(_mnn_tensor_copy_to_host( - self, - host_tensor, - )); +@ffi.Native() +external VARP_t mnn_expr_Fill( + VARP_t dims, + VARP_t value, +); -/// @brief Create tensor with dimension size and type -/// @param dim_size Dimension size -/// @param type Dimension type -/// @return Tensor instance or NULL if failed -@ffi.Native( - symbol: 'mnn_tensor_create') -external mnn_tensor_t _mnn_tensor_create( - int dim_size, - int type, +@ffi.Native() +external VARP_t mnn_expr_FloatToInt8( + VARP_t x, + VARP_t scale, + int minValue, + int maxValue, ); -mnn_tensor_t mnn_tensor_create( - int dim_size, - DimensionType type, -) => - _mnn_tensor_create( - dim_size, - type.value, - ); +@ffi.Native() +external VARP_t mnn_expr_FloatToInt8_1( + VARP_t x, + VARP_t scale, + int minValue, + int maxValue, + int zeroPoint, +); -/// @brief Create device tensor -/// @param shape Tensor shape array -/// @param shape_size Shape array size -/// @param type Data type -/// @param dim_type Dimension type -/// @return Tensor instance or NULL if failed -@ffi.Native< - mnn_tensor_t Function(ffi.Pointer, ffi.Int, halide_type_c_t, - ffi.UnsignedInt)>(symbol: 'mnn_tensor_create_device') -external mnn_tensor_t _mnn_tensor_create_device( - ffi.Pointer shape, - int shape_size, - halide_type_c_t type, - int dim_type, +@ffi.Native() +external VARP_t mnn_expr_Floor( + VARP_t x, ); -mnn_tensor_t mnn_tensor_create_device( - ffi.Pointer shape, - int shape_size, - halide_type_c_t type, - DimensionType dim_type, -) => - _mnn_tensor_create_device( - shape, - shape_size, - type, - dim_type.value, - ); +@ffi.Native() +external VARP_t mnn_expr_FloorDiv( + VARP_t x, + VARP_t y, +); -/// @brief Create tensor with same shape as given tensor -/// @param self Shape provider -/// @param type Dimension type -/// @param alloc_memory Whether allocate memory -/// @return Tensor instance or NULL if failed -@ffi.Native( - symbol: 'mnn_tensor_create_from_tensor') -external mnn_tensor_t _mnn_tensor_create_from_tensor( - mnn_tensor_t self, - int type, - bool alloc_memory, +@ffi.Native() +external VARP_t mnn_expr_FloorMod( + VARP_t x, + VARP_t y, ); -mnn_tensor_t mnn_tensor_create_from_tensor( - mnn_tensor_t self, - DimensionType type, - bool alloc_memory, -) => - _mnn_tensor_create_from_tensor( - self, - type.value, - alloc_memory, - ); +@ffi.Native() +external VARP_t mnn_expr_Gather( + VARP_t params, + VARP_t indices, +); -/// @brief Create tensor with data -/// @param shape Tensor shape array -/// @param shape_size Shape array size -/// @param type Data type -/// @param data Data pointer -/// @param dim_type Dimension type -/// @return Tensor instance or NULL if failed -@ffi.Native< - mnn_tensor_t Function( - ffi.Pointer, - ffi.Int, - halide_type_c_t, - ffi.Pointer, - ffi.UnsignedInt)>(symbol: 'mnn_tensor_create_with_data') -external mnn_tensor_t _mnn_tensor_create_with_data( - ffi.Pointer shape, - int shape_size, - halide_type_c_t type, - ffi.Pointer data, - int dim_type, +@ffi.Native() +external VARP_t mnn_expr_GatherElements( + VARP_t params, + VARP_t indices, ); -mnn_tensor_t mnn_tensor_create_with_data( - ffi.Pointer shape, - int shape_size, - halide_type_c_t type, - ffi.Pointer data, - DimensionType dim_type, -) => - _mnn_tensor_create_with_data( - shape, - shape_size, - type, - data, - dim_type.value, - ); +@ffi.Native() +external VARP_t mnn_expr_GatherElements_1( + VARP_t params, + VARP_t indices, + VARP_t axis, +); -/// @brief Destroy tensor -/// @param tensor Tensor to destroy -@ffi.Native(isLeaf: true) -external void mnn_tensor_destroy( - mnn_tensor_t tensor, +@ffi.Native() +external VARP_t mnn_expr_GatherND( + VARP_t params, + VARP_t indices, ); -/// @brief Get device ID -/// @param self Tensor -/// @return Device ID -@ffi.Native(isLeaf: true) -external int mnn_tensor_device_id( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_GatherV2( + VARP_t params, + VARP_t indices, + VARP_t axis, ); -/// @brief Get tensor dimensions -/// @param self Tensor -/// @return Dimension count -@ffi.Native(isLeaf: true) -external int mnn_tensor_dimensions( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_Gelu( + VARP_t x, ); -/// @brief Get tensor element count -/// @param self Tensor -/// @return Element count -@ffi.Native(isLeaf: true) -external int mnn_tensor_element_size( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_Greater( + VARP_t x, + VARP_t y, ); -/// @brief Get dimension type -/// @param self Tensor -/// @return Dimension type -@ffi.Native( - symbol: 'mnn_tensor_get_dimension_type', isLeaf: true) -external int _mnn_tensor_get_dimension_type( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_GreaterEqual( + VARP_t x, + VARP_t y, ); -DimensionType mnn_tensor_get_dimension_type( - mnn_tensor_t self, -) => - DimensionType.fromValue(_mnn_tensor_get_dimension_type( - self, - )); +/// enum GridSamplePaddingMode {GRID_SAMPLE_PADDING_ZEROS, GRID_SAMPLE_PADDING_BORDER, +/// GRID_SAMPLE_PADDING_REFLECTION}; +@ffi.Native() +external VARP_t mnn_expr_GridSample( + VARP_t input, + VARP_t grid, + int mode, + int paddingMode, + bool alignCorners, +); -/// @brief Get handle data type -/// @param self Tensor -/// @return Handle data type -@ffi.Native( - symbol: 'mnn_tensor_get_handle_data_type', isLeaf: true) -external int _mnn_tensor_get_handle_data_type( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_Hardswish( + VARP_t x, ); -HandleDataType mnn_tensor_get_handle_data_type( - mnn_tensor_t self, -) => - HandleDataType.fromValue(_mnn_tensor_get_handle_data_type( - self, - )); +@ffi.Native() +external VARP_t mnn_expr_Histogram( + VARP_t x, + int bin, + int min, + int max, + int channel, +); -/// @brief Get data type -/// @param self Tensor -/// @return Data type -@ffi.Native Function(mnn_tensor_t)>(isLeaf: true) -external ffi.Pointer mnn_tensor_get_type( - mnn_tensor_t self, +@ffi.Native< + VARP_t Function( + VARP_t, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size)>() +external VARP_t mnn_expr_Im2Col( + VARP_t x, + ffi.Pointer kernelSize, + int kernelSizeLength, + ffi.Pointer dilate, + int dilateLength, + ffi.Pointer pads, + int padsLength, + ffi.Pointer stride, + int strideLength, +); + +/// Neural Network Ops +@ffi.Native< + VARP_t Function(ffi.Pointer, ffi.Size, ffi.Int, halide_type_c_t)>() +external VARP_t mnn_expr_Input( + ffi.Pointer shape, + int shapeLength, + int data_format, + halide_type_c_t dtype, +); + +@ffi.Native() +external VARP_t mnn_expr_Int8ToFloat( + VARP_t x, + VARP_t scale, +); + +@ffi.Native() +external VARP_t mnn_expr_Int8ToFloat_1( + VARP_t x, + VARP_t scale, + int zeroPoint, +); + +/// MNN_PUBLIC VARP _DetectionOutput(VARP location, VARP confidence, VARP priorbox, +/// unsigned int num_classes, bool share_location, int background_label_id, +/// float nms_threshhold, int nms_topk, int code_type, +/// bool variance_encoded_in_target, +/// int keep_top_k, float confidence_threshold, float visualize_threshold); +/// MNN_PUBLIC std::vector _DetectionPostProcess(VARP encode_boxes, VARP class_predictions, +/// VARP anchors, +/// int num_classes, int max_detections, +/// int max_class_per_detection, int detections_per_class, +/// float nms_threshold, float iou_threshold, +/// bool use_regular_nms, std::vector centersize_encoding); +@ffi.Native< + VARP_t Function( + VecVARP_t, ffi.Float, ffi.Float, ffi.Int, ffi.Int, ffi.Int, ffi.Bool)>() +external VARP_t mnn_expr_Interp( + VecVARP_t xs, + double widthScale, + double heightScale, + int outputWidth, + int outputHeight, + int resizeType, + bool alignCorners, ); -/// @brief Get tensor height -/// @param self Tensor -/// @return Height -@ffi.Native(isLeaf: true) -external int mnn_tensor_height( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_Less( + VARP_t x, + VARP_t y, ); -/// @brief Get host data pointer -/// @param self Tensor -/// @return Data pointer or NULL -@ffi.Native Function(mnn_tensor_t)>(isLeaf: true) -external ffi.Pointer mnn_tensor_host( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_LessEqual( + VARP_t x, + VARP_t y, ); -/// @brief Get tensor length -/// @param self Tensor -/// @param index Dimension index -/// @return Length -@ffi.Native(isLeaf: true) -external int mnn_tensor_length( - mnn_tensor_t self, - int index, +@ffi.Native() +external VARP_t mnn_expr_LinSpace( + VARP_t start, + VARP_t stop, + VARP_t num, ); -/// @brief Map tensor for access -/// @param self Tensor -/// @param mtype Map type -/// @param dtype Dimension type -/// @return Mapped pointer or NULL -@ffi.Native< - ffi.Pointer Function(mnn_tensor_t, ffi.UnsignedInt, - ffi.UnsignedInt)>(symbol: 'mnn_tensor_map', isLeaf: true) -external ffi.Pointer _mnn_tensor_map( - mnn_tensor_t self, - int mtype, - int dtype, +@ffi.Native() +external VARP_t mnn_expr_Log( + VARP_t x, ); -ffi.Pointer mnn_tensor_map( - mnn_tensor_t self, - MapType mtype, - DimensionType dtype, -) => - _mnn_tensor_map( - self, - mtype.value, - dtype.value, - ); +@ffi.Native() +external VARP_t mnn_expr_Log1p( + VARP_t x, +); -@ffi.Native() -external void mnn_tensor_print( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_LogicalOr( + VARP_t x, + VARP_t y, ); -@ffi.Native() -external void mnn_tensor_print_shape( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_MatMul( + VARP_t a, + VARP_t b, + bool tranposeA, + bool tranposeB, +); + +@ffi.Native() +external VARP_t mnn_expr_MatrixBandPart( + VARP_t input, + VARP_t num_lower, + VARP_t num_upper, +); + +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_Max( + VARP_t a, + VARP_t b, + ffi.Pointer coeff, + int coeffSize, ); -/// @brief Set device pointer -/// @param self Tensor -/// @param device_ptr Device pointer -/// @param memory_type Memory type -/// @return Error code @ffi.Native< - ffi.UnsignedInt Function(mnn_tensor_t, ffi.Pointer, ffi.Int)>( - symbol: 'mnn_tensor_set_device_ptr', isLeaf: true) -external int _mnn_tensor_set_device_ptr( - mnn_tensor_t self, - ffi.Pointer device_ptr, - int memory_type, + VARP_t Function( + VARP_t, + ffi.Pointer, + ffi.Size, + ffi.Pointer, + ffi.Size, + ffi.Int, + ffi.Pointer, + ffi.Size)>() +external VARP_t mnn_expr_MaxPool( + VARP_t x, + ffi.Pointer kernel, + int kernelLength, + ffi.Pointer stride, + int strideLength, + int pad, + ffi.Pointer pads, + int padsLength, +); + +@ffi.Native() +external VARP_t mnn_expr_Maximum( + VARP_t x, + VARP_t y, +); + +@ffi.Native() +external VARP_t mnn_expr_Minimum( + VARP_t x, + VARP_t y, +); + +/// MNN_PUBLIC VARP _EltwiseProdInt8(VARP x, VARP y, +/// std::vector x_weight, std::vector x_bias, std::vector +/// x_scale, std::vector x_tensorScale, std::vector y_weight, +/// std::vector y_bias, std::vector y_scale, std::vector +/// y_tensorScale, std::vector output_weight, std::vector +/// output_bias, std::vector output_scale, std::vector +/// output_tensorScale); +/// MNN_PUBLIC VARP _EltwiseSumInt8(VARP x, VARP y, +/// std::vector x_weight, std::vector x_bias, +/// std::vector x_scale, std::vector x_tensorScale, +/// std::vector y_weight, std::vector y_bias, std::vector +/// y_scale, std::vector y_tensorScale, std::vector output_weight, +/// std::vector output_bias, std::vector output_scale, +/// std::vector output_tensorScale); +/// MNN_PUBLIC VARP _EltwiseSubInt8(VARP x, VARP y, +/// std::vector x_weight, std::vector x_bias, +/// std::vector x_scale, std::vector x_tensorScale, +/// std::vector y_weight, std::vector y_bias, std::vector +/// y_scale, std::vector y_tensorScale, std::vector output_weight, +/// std::vector output_bias, std::vector output_scale, +/// std::vector output_tensorScale); +/// MNN_PUBLIC VARP _EltwiseMaxInt8(VARP x, VARP y, +/// std::vector x_weight, std::vector x_bias, +/// std::vector x_scale, std::vector x_tensorScale, +/// std::vector y_weight, std::vector y_bias, std::vector +/// y_scale, std::vector y_tensorScale, std::vector output_weight, +/// std::vector output_bias, std::vector output_scale, +/// std::vector output_tensorScale); +@ffi.Native() +external VARP_t mnn_expr_Mod( + VARP_t x, + VARP_t y, ); -ErrorCode mnn_tensor_set_device_ptr( - mnn_tensor_t self, - ffi.Pointer device_ptr, - int memory_type, -) => - ErrorCode.fromValue(_mnn_tensor_set_device_ptr( - self, - device_ptr, - memory_type, - )); +@ffi.Native< + VecVARP_t Function( + VARP_t, ffi.Pointer, ffi.Size, VARP_t, ffi.Bool)>() +external VecVARP_t mnn_expr_Moments( + VARP_t x, + ffi.Pointer axis, + int axisLength, + VARP_t shift, + bool keepDims, +); + +@ffi.Native() +external VARP_t mnn_expr_Multiply( + VARP_t x, + VARP_t y, +); + +@ffi.Native() +external VARP_t mnn_expr_Negative( + VARP_t x, +); + +@ffi.Native() +external VARP_t mnn_expr_Nms( + VARP_t boxes, + VARP_t scores, + int maxDetections, + double iouThreshold, + double scoreThreshold, +); @ffi.Native< - ffi.UnsignedInt Function( - mnn_tensor_t, - ffi.Int, - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int)>(symbol: 'mnn_tensor_set_image_f32', isLeaf: true) -external int _mnn_tensor_set_image_f32( - mnn_tensor_t self, - int index, - ffi.Pointer data, - int width, - int height, - int channel, + VARP_t Function(VARP_t, ffi.Int32, ffi.Int32, ffi.Float, + ffi.Pointer, ffi.Size)>() +external VARP_t mnn_expr_Normalize( + VARP_t x, + int acrossSpatial, + int channelShared, + double eps, + ffi.Pointer scale, + int scaleLength, +); + +@ffi.Native() +external VARP_t mnn_expr_NotEqual( + VARP_t x, + VARP_t y, +); + +@ffi.Native() +external VARP_t mnn_expr_OneHot( + VARP_t indices, + VARP_t depth, + VARP_t onValue, + VARP_t offValue, + int axis, +); + +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_PRelu( + VARP_t x, + ffi.Pointer slopes, + int slopeLength, +); + +@ffi.Native() +external VARP_t mnn_expr_Pad( + VARP_t x, + VARP_t paddings, + int mode, ); -ErrorCode mnn_tensor_set_image_f32( - mnn_tensor_t self, - int index, - ffi.Pointer data, - int width, - int height, - int channel, -) => - ErrorCode.fromValue(_mnn_tensor_set_image_f32( - self, - index, - data, - width, - height, - channel, - )); +/// MNN_PUBLIC VARP _PriorBox(VARP feature, VARP image, +/// std::vector min_size, std::vector max_size, +/// std::vectoraspect_ratio, bool flip, bool clip, +/// std::vectorvariance, unsigned int img_h, unsigned int img_w, +/// float step_h, float step_w, float offset = 0.5); +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_Permute( + VARP_t input, + ffi.Pointer dims, + int dimsLength, +); -/// @brief Set tensor length -/// @param self Tensor -/// @param index Dimension index -/// @param length Length value -@ffi.Native(isLeaf: true) -external void mnn_tensor_set_length( - mnn_tensor_t self, - int index, - int length, +@ffi.Native() +external VARP_t mnn_expr_Pow( + VARP_t x, + VARP_t y, ); -/// @brief Set tensor stride -/// @param self Tensor -/// @param index Dimension index -/// @param stride Stride value -@ffi.Native(isLeaf: true) -external void mnn_tensor_set_stride( - mnn_tensor_t self, - int index, - int stride, +/// EltwiseOPs +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_Prod( + VARP_t a, + VARP_t b, + ffi.Pointer coeff, + int coeffSize, ); -/// @brief Set data type -/// @param self Tensor -/// @param type Data type -@ffi.Native(isLeaf: true) -external void mnn_tensor_set_type( - mnn_tensor_t self, - int type, +@ffi.Native< + VARP_t Function( + VARP_t, halide_type_c_t, ffi.Float, ffi.Float, ffi.Int, ffi.Int)>() +external VARP_t mnn_expr_RandomUniform( + VARP_t shape, + halide_type_c_t dtype, + double low, + double high, + int seed0, + int seed1, +); + +@ffi.Native() +external VARP_t mnn_expr_Range( + VARP_t start, + VARP_t limit, + VARP_t delta, +); + +@ffi.Native() +external VARP_t mnn_expr_Rank( + VARP_t input, ); -/// @brief Get tensor shape -/// @param self Tensor -/// @param shape Output shape array (must be pre-allocated) -/// @param shape_size Shape array size -/// @return Error code @ffi.Native< - ffi.UnsignedInt Function(mnn_tensor_t, ffi.Pointer, ffi.Int)>( - symbol: 'mnn_tensor_shape', isLeaf: true) -external int _mnn_tensor_shape( - mnn_tensor_t self, + VARP_t Function(VecVARP_t, ffi.Pointer, ffi.Size, + ffi.Pointer, ffi.Size)>() +external VARP_t mnn_expr_Raster( + VecVARP_t vars, + ffi.Pointer regions, + int regionsLength, ffi.Pointer shape, - int shape_size, + int shapeLength, ); -ErrorCode mnn_tensor_shape( - mnn_tensor_t self, +@ffi.Native< + VARP_t Function(VecVARP_t, ffi.Pointer, ffi.Size, + ffi.Pointer, ffi.Size, halide_type_t, ffi.Int)>() +external VARP_t mnn_expr_RasterRaw( + VecVARP_t vars, + ffi.Pointer region, + int regionLength, ffi.Pointer shape, - int shape_size, -) => - ErrorCode.fromValue(_mnn_tensor_shape( - self, - shape, - shape_size, - )); + int shapeLength, + halide_type_t dataType, + int format, +); -/// @brief Get tensor data size in bytes -/// @param self Tensor -/// @return Size in bytes -@ffi.Native(isLeaf: true) -external int mnn_tensor_size( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_Reciprocal( + VARP_t x, ); -/// @brief Get tensor stride -/// @param self Tensor -/// @param index Dimension index -/// @return Stride -@ffi.Native(isLeaf: true) -external int mnn_tensor_stride( - mnn_tensor_t self, - int index, +@ffi.Native() +external VARP_t mnn_expr_ReduceAll( + VARP_t input_variable, + VecI32 axis, + bool keepDims, ); -/// @brief Unmap tensor -/// @param self Tensor -/// @param mtype Map type -/// @param dtype Dimension type -/// @param map_ptr Mapped pointer -@ffi.Native< - ffi.Void Function(mnn_tensor_t, ffi.UnsignedInt, ffi.UnsignedInt, - ffi.Pointer)>(symbol: 'mnn_tensor_unmap', isLeaf: true) -external void _mnn_tensor_unmap( - mnn_tensor_t self, - int mtype, - int dtype, - ffi.Pointer map_ptr, +@ffi.Native() +external VARP_t mnn_expr_ReduceAllMutable( + VARP_t input_variable, + VARP_t axis, + bool keepDims, ); -void mnn_tensor_unmap( - mnn_tensor_t self, - MapType mtype, - DimensionType dtype, - ffi.Pointer map_ptr, -) => - _mnn_tensor_unmap( - self, - mtype.value, - dtype.value, - map_ptr, - ); +@ffi.Native() +external VARP_t mnn_expr_ReduceAny( + VARP_t input_variable, + VecI32 axis, + bool keepDims, +); -/// @brief Get tensor shape in bytes (unsigned) -/// @param self Tensor -/// @return Size in bytes -@ffi.Native(isLeaf: true) -external int mnn_tensor_usize( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_ReduceAnyMutable( + VARP_t input_variable, + VARP_t axis, + bool keepDims, ); -/// @brief Wait for tensor ready -/// @param self Tensor -/// @param mtype Map type -/// @param finish Whether wait for finish -/// @return Error code -@ffi.Native( - symbol: 'mnn_tensor_wait') -external int _mnn_tensor_wait( - mnn_tensor_t self, - int mtype, - bool finish, +@ffi.Native() +external VARP_t mnn_expr_ReduceMax( + VARP_t input_variable, + VecI32 axis, + bool keepDims, ); -ErrorCode mnn_tensor_wait( - mnn_tensor_t self, - MapType mtype, - bool finish, -) => - ErrorCode.fromValue(_mnn_tensor_wait( - self, - mtype.value, - finish, - )); +@ffi.Native() +external VARP_t mnn_expr_ReduceMaxMutable( + VARP_t input_variable, + VARP_t axis, + bool keepDims, +); -/// @brief Get tensor width -/// @param self Tensor -/// @return Width -@ffi.Native(isLeaf: true) -external int mnn_tensor_width( - mnn_tensor_t self, +@ffi.Native() +external VARP_t mnn_expr_ReduceMean( + VARP_t input_variable, + VecI32 axis, + bool keepDims, ); -/// @brief Creates a new timer instance -/// @return Pointer to the newly created timer -@ffi.Native() -external mnn_timer_t mnn_timer_create(); +@ffi.Native() +external VARP_t mnn_expr_ReduceMeanMutable( + VARP_t input_variable, + VARP_t axis, + bool keepDims, +); -/// @brief Gets the current time value from timer -/// @param timer Timer instance to query -/// @return Current time value -@ffi.Native() -external int mnn_timer_current( - mnn_timer_t timer, +@ffi.Native() +external VARP_t mnn_expr_ReduceMin( + VARP_t input_variable, + VecI32 axis, + bool keepDims, ); -/// @brief Destroys a timer instance -/// @param timer Timer instance to destroy -@ffi.Native() -external void mnn_timer_destroy( - mnn_timer_t timer, +@ffi.Native() +external VARP_t mnn_expr_ReduceMinMutable( + VARP_t input_variable, + VARP_t axis, + bool keepDims, ); -/// @brief Gets the duration in microseconds since last reset -/// @param timer Timer instance to query -/// @return Duration in microseconds -@ffi.Native() -external int mnn_timer_duration_us( - mnn_timer_t timer, +@ffi.Native() +external VARP_t mnn_expr_ReduceProd( + VARP_t input_variable, + VecI32 axis, + bool keepDims, ); -/// @brief Resets the timer to current time -/// @param timer Timer instance to reset -@ffi.Native() -external void mnn_timer_reset( - mnn_timer_t timer, +@ffi.Native() +external VARP_t mnn_expr_ReduceProdMutable( + VARP_t input_variable, + VARP_t axis, + bool keepDims, ); -/// indicate whether we should process iphone images back to canonical format, -/// or just pass them through "as-is" -@ffi.Native() -external void stbi_convert_iphone_png_to_rgb( - int flag_true_if_should_convert, +/// ReduceOPs +@ffi.Native() +external VARP_t mnn_expr_ReduceSum( + VARP_t input_variable, + VecI32 axis, + bool keepDims, ); -@ffi.Native() -external void stbi_convert_iphone_png_to_rgb_thread( - int flag_true_if_should_convert, +@ffi.Native() +external VARP_t mnn_expr_ReduceSumMutable( + VARP_t input_variable, + VARP_t axis, + bool keepDims, ); -/// get a VERY brief reason for failure -/// on most compilers (and ALL modern mainstream compilers) this is threadsafe -@ffi.Native Function()>() -external ffi.Pointer stbi_failure_reason(); +@ffi.Native() +external VARP_t mnn_expr_Relu( + VARP_t x, + double slope, +); -@ffi.Native() -external void stbi_flip_vertically_on_write( - int flip_boolean, +@ffi.Native() +external VARP_t mnn_expr_Relu6( + VARP_t x, + double minValue, + double maxValue, ); -@ffi.Native() -external void stbi_hdr_to_ldr_gamma( - double gamma, +@ffi.Native, ffi.Size, ffi.Int)>() +external VARP_t mnn_expr_Reshape( + VARP_t x, + ffi.Pointer shape, + int shapeLength, + int original_format, ); -@ffi.Native() -external void stbi_hdr_to_ldr_scale( - double scale, +@ffi.Native() +external VARP_t mnn_expr_Reshape_1( + VARP_t x, + VARP_t shape, ); -/// free the loaded image -- this is just free() -@ffi.Native)>() -external void stbi_image_free( - ffi.Pointer retval_from_stbi_load, +@ffi.Native() +external VARP_t mnn_expr_Resize( + VARP_t images, + double xScale, + double yScale, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer)>() -external int stbi_info( - ffi.Pointer filename, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer comp, +@ffi.Native() +external VARP_t mnn_expr_Reverse( + VARP_t x, + VARP_t axis, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer, ffi.Pointer)>() -external int stbi_info_from_callbacks( - ffi.Pointer clbk, - ffi.Pointer user, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer comp, +@ffi.Native() +external VARP_t mnn_expr_ReverseSequence( + VARP_t x, + VARP_t y, + int batchDim, + int seqDim, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer)>() -external int stbi_info_from_file( - ffi.Pointer f, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer comp, +@ffi.Native() +external VARP_t mnn_expr_Round( + VARP_t x, ); -/// get image dimensions & components without fully decoding -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Pointer, - ffi.Pointer, ffi.Pointer)>() -external int stbi_info_from_memory( - ffi.Pointer buffer, - int len, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer comp, +@ffi.Native() +external VARP_t mnn_expr_Rsqrt( + VARP_t x, ); -@ffi.Native)>() -external int stbi_is_16_bit( - ffi.Pointer filename, +@ffi.Native, halide_type_c_t)>() +external VARP_t mnn_expr_Scalar( + ffi.Pointer ptr, + halide_type_c_t type, ); @ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer)>() -external int stbi_is_16_bit_from_callbacks( - ffi.Pointer clbk, - ffi.Pointer user, + VARP_t Function(VARP_t, ffi.Int, ffi.Pointer, ffi.Size, + ffi.Pointer, ffi.Size)>() +external VARP_t mnn_expr_Scale( + VARP_t x, + int channels, + ffi.Pointer scales, + int scaleLength, + ffi.Pointer bias, + int biasLength, +); + +@ffi.Native() +external VARP_t mnn_expr_ScatterElements( + VARP_t data, + VARP_t indices, + VARP_t updates, + int reduction, +); + +@ffi.Native() +external VARP_t mnn_expr_ScatterElements_1( + VARP_t data, + VARP_t indices, + VARP_t updates, + VARP_t axis, + int reduction, +); + +@ffi.Native() +external VARP_t mnn_expr_ScatterNd( + VARP_t indices, + VARP_t updates, + VARP_t shape, +); + +@ffi.Native() +external VARP_t mnn_expr_ScatterNd_1( + VARP_t indices, + VARP_t updates, + VARP_t shape, + VARP_t input, +); + +@ffi.Native() +external VARP_t mnn_expr_ScatterNd_2( + VARP_t indices, + VARP_t updates, + VARP_t shape, + int reduction, +); + +@ffi.Native() +external VARP_t mnn_expr_ScatterNd_3( + VARP_t indices, + VARP_t updates, + VARP_t shape, + VARP_t input, + int reduction, +); + +@ffi.Native() +external VARP_t mnn_expr_Select( + VARP_t select, + VARP_t input0, + VARP_t input1, +); + +@ffi.Native() +external VARP_t mnn_expr_Selu( + VARP_t features, + double scale, + double alpha, ); -@ffi.Native)>() -external int stbi_is_16_bit_from_file( - ffi.Pointer f, +@ffi.Native() +external VARP_t mnn_expr_SetDiff1D( + VARP_t x, + VARP_t y, ); -@ffi.Native, ffi.Int)>() -external int stbi_is_16_bit_from_memory( - ffi.Pointer buffer, - int len, +@ffi.Native() +external VARP_t mnn_expr_Shape( + VARP_t input, + bool nchw, ); -@ffi.Native)>() -external int stbi_is_hdr( - ffi.Pointer filename, +@ffi.Native() +external VARP_t mnn_expr_Sigmoid( + VARP_t x, ); -/// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer)>() -external int stbi_is_hdr_from_callbacks( - ffi.Pointer clbk, - ffi.Pointer user, +/// UnaryOPs +@ffi.Native() +external VARP_t mnn_expr_Sign( + VARP_t a, ); -@ffi.Native)>() -external int stbi_is_hdr_from_file( - ffi.Pointer f, +@ffi.Native() +external VARP_t mnn_expr_Silu( + VARP_t x, ); -@ffi.Native, ffi.Int)>() -external int stbi_is_hdr_from_memory( - ffi.Pointer buffer, - int len, +@ffi.Native() +external VARP_t mnn_expr_Sin( + VARP_t x, ); -@ffi.Native() -external void stbi_ldr_to_hdr_gamma( - double gamma, +@ffi.Native() +external VARP_t mnn_expr_Sinh( + VARP_t x, ); -@ffi.Native() -external void stbi_ldr_to_hdr_scale( - double scale, +@ffi.Native() +external VARP_t mnn_expr_Size( + VARP_t input, ); -@ffi.Native< - ffi.Pointer Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer, ffi.Int)>() -external ffi.Pointer stbi_load( - ffi.Pointer filename, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_Slice( + VARP_t x, + VARP_t starts, + VARP_t sizes, ); -@ffi.Native< - ffi.Pointer Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer, ffi.Int)>() -external ffi.Pointer stbi_load_16( - ffi.Pointer filename, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_Softmax( + VARP_t logits, + int axis, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Int)>() -external ffi.Pointer stbi_load_16_from_callbacks( - ffi.Pointer clbk, - ffi.Pointer user, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_Softplus( + VARP_t features, ); -/// ///////////////////////////////// -/// -/// 16-bits-per-channel interface -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Int, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Int)>() -external ffi.Pointer stbi_load_16_from_memory( - ffi.Pointer buffer, - int len, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_Softsign( + VARP_t features, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Int)>() -external ffi.Pointer stbi_load_from_callbacks( - ffi.Pointer clbk, - ffi.Pointer user, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_Sort( + VARP_t x, + int axis, + bool arg, + bool descend, ); -@ffi.Native< - ffi.Pointer Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer, ffi.Int)>() -external ffi.Pointer stbi_load_from_file( - ffi.Pointer f, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_SpaceToBatchND( + VARP_t input, + VARP_t block_shape, + VARP_t paddings, ); -@ffi.Native< - ffi.Pointer Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer, ffi.Int)>() -external ffi.Pointer stbi_load_from_file_16( - ffi.Pointer f, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_SpaceToDepth( + VARP_t input, + int block_size, ); -/// ///////////////////////////////// -/// -/// 8-bits-per-channel interface @ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Int, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Int)>() -external ffi.Pointer stbi_load_from_memory( - ffi.Pointer buffer, - int len, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, + VecVARP_t Function(VARP_t, ffi.Pointer, ffi.Size, ffi.Int)>() +external VecVARP_t mnn_expr_Split( + VARP_t value, + ffi.Pointer size_splits, + int size_splitsLength, + int axis, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Int, - ffi.Pointer>, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Int)>() -external ffi.Pointer stbi_load_gif_from_memory( - ffi.Pointer buffer, - int len, - ffi.Pointer> delays, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer z, - ffi.Pointer comp, - int req_comp, +@ffi.Native() +external VARP_t mnn_expr_Sqrt( + VARP_t x, ); -@ffi.Native< - ffi.Pointer Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer, ffi.Int)>() -external ffi.Pointer stbi_loadf( - ffi.Pointer filename, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_Square( + VARP_t x, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Int)>() -external ffi.Pointer stbi_loadf_from_callbacks( - ffi.Pointer clbk, - ffi.Pointer user, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, +@ffi.Native() +external VARP_t mnn_expr_SquaredDifference( + VARP_t x, + VARP_t y, +); + +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_Squeeze( + VARP_t input, + ffi.Pointer axis, + int axisLength, +); + +@ffi.Native() +external VARP_t mnn_expr_Stack( + VecVARP_t values, + int axis, ); @ffi.Native< - ffi.Pointer Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, ffi.Pointer, ffi.Int)>() -external ffi.Pointer stbi_loadf_from_file( - ffi.Pointer f, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, + VARP_t Function(VARP_t, VARP_t, VARP_t, VARP_t, ffi.Int32, ffi.Int32, + ffi.Int32, ffi.Int32, ffi.Int32)>() +external VARP_t mnn_expr_StridedSlice( + VARP_t input, + VARP_t begin, + VARP_t end, + VARP_t strided, + int beginMask, + int endMask, + int ellipsisMask, + int newAxisMask, + int shrinkAxisMask, ); @ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Int, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Int)>() -external ffi.Pointer stbi_loadf_from_memory( - ffi.Pointer buffer, - int len, - ffi.Pointer x, - ffi.Pointer y, - ffi.Pointer channels_in_file, - int desired_channels, + VARP_t Function(VARP_t, VARP_t, VARP_t, VARP_t, VARP_t, ffi.Int32, + ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32)>() +external VARP_t mnn_expr_StridedSliceWrite( + VARP_t input, + VARP_t begin, + VARP_t end, + VARP_t strided, + VARP_t write, + int beginMask, + int endMask, + int ellipsisMask, + int newAxisMask, + int shrinkAxisMask, ); -/// flip the image vertically, so the first pixel in the output array is the bottom left -@ffi.Native() -external void stbi_set_flip_vertically_on_load( - int flag_true_if_should_flip, +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_Sub( + VARP_t a, + VARP_t b, + ffi.Pointer coeff, + int coeffSize, ); -@ffi.Native() -external void stbi_set_flip_vertically_on_load_thread( - int flag_true_if_should_flip, +@ffi.Native() +external VARP_t mnn_expr_Subtract( + VARP_t x, + VARP_t y, ); -/// for image formats that explicitly notate that they have premultiplied alpha, -/// we just return the colors as stored in the file. set this flag to force -/// unpremultiplication. results are undefined if the unpremultiply overflow. -@ffi.Native() -external void stbi_set_unpremultiply_on_load( - int flag_true_if_should_unpremultiply, +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_Sum( + VARP_t a, + VARP_t b, + ffi.Pointer coeff, + int coeffSize, ); -/// as above, but only applies to images loaded on the thread that calls the function -/// this function is only available if your compiler supports thread-local variables; -/// calling it will fail to link if your compiler doesn't -@ffi.Native() -external void stbi_set_unpremultiply_on_load_thread( - int flag_true_if_should_unpremultiply, +@ffi.Native() +external VecVARP_t mnn_expr_Svd( + VARP_t x, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, - ffi.Pointer)>() -external int stbi_write_bmp( - ffi.Pointer filename, - int w, - int h, - int comp, - ffi.Pointer data, +@ffi.Native() +external VARP_t mnn_expr_Tan( + VARP_t x, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer, - ffi.Int, ffi.Int, ffi.Int, ffi.Pointer)>() -external int stbi_write_bmp_to_func( - ffi.Pointer func, - ffi.Pointer context, - int w, - int h, - int comp, - ffi.Pointer data, +@ffi.Native() +external VARP_t mnn_expr_Tanh( + VARP_t x, ); -@ffi.Native() -external int stbi_write_force_png_filter; - -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, - ffi.Pointer)>() -external int stbi_write_hdr( - ffi.Pointer filename, - int w, - int h, - int comp, - ffi.Pointer data, +@ffi.Native() +external VARP_t mnn_expr_Threshold( + VARP_t features, + double alpha, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer, - ffi.Int, ffi.Int, ffi.Int, ffi.Pointer)>() -external int stbi_write_hdr_to_func( - ffi.Pointer func, - ffi.Pointer context, - int w, - int h, - int comp, - ffi.Pointer data, +@ffi.Native() +external VARP_t mnn_expr_Tile( + VARP_t input, + VARP_t multiples, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, - ffi.Pointer, ffi.Int)>() -external int stbi_write_jpg( - ffi.Pointer filename, - int x, - int y, - int comp, - ffi.Pointer data, - int quality, +@ffi.Native() +external VecVARP_t mnn_expr_TopKV2( + VARP_t input0, + VARP_t input1, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer, - ffi.Int, ffi.Int, ffi.Int, ffi.Pointer, ffi.Int)>() -external int stbi_write_jpg_to_func( - ffi.Pointer func, - ffi.Pointer context, - int x, - int y, - int comp, - ffi.Pointer data, - int quality, +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_Transpose( + VARP_t x, + ffi.Pointer perm, + int permLength, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, - ffi.Pointer, ffi.Int)>() -external int stbi_write_png( - ffi.Pointer filename, - int w, - int h, - int comp, - ffi.Pointer data, - int stride_in_bytes, +@ffi.Native() +external VARP_t mnn_expr_Transpose_1( + VARP_t x, + VARP_t perm, ); -@ffi.Native() -external int stbi_write_png_compression_level; - -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer, - ffi.Int, ffi.Int, ffi.Int, ffi.Pointer, ffi.Int)>() -external int stbi_write_png_to_func( - ffi.Pointer func, - ffi.Pointer context, - int w, - int h, - int comp, - ffi.Pointer data, - int stride_in_bytes, +@ffi.Native() +external VARP_t mnn_expr_UnravelIndex( + VARP_t indices, + VARP_t dims, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, - ffi.Pointer)>() -external int stbi_write_tga( - ffi.Pointer filename, - int w, - int h, - int comp, - ffi.Pointer data, +@ffi.Native, ffi.Size)>() +external VARP_t mnn_expr_Unsqueeze( + VARP_t input, + ffi.Pointer axis, + int axisLength, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Pointer, - ffi.Int, ffi.Int, ffi.Int, ffi.Pointer)>() -external int stbi_write_tga_to_func( - ffi.Pointer func, - ffi.Pointer context, - int w, - int h, - int comp, - ffi.Pointer data, +@ffi.Native() +external VecVARP_t mnn_expr_Unstack( + VARP_t value, + int axis, ); -@ffi.Native() -external int stbi_write_tga_with_rle; +@ffi.Native() +external VARMAP_t mnn_expr_VARMAP_create(); -@ffi.Native< - ffi.Int Function( - ffi.Pointer, ffi.Int, ffi.Pointer, ffi.Int)>() -external int stbi_zlib_decode_buffer( - ffi.Pointer obuffer, - int olen, - ffi.Pointer ibuffer, - int ilen, +@ffi.Native)>() +external void mnn_expr_VARMAP_free( + ffi.Pointer self, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, ffi.Int, ffi.Pointer)>() -external ffi.Pointer stbi_zlib_decode_malloc( - ffi.Pointer buffer, - int len, - ffi.Pointer outlen, +@ffi.Native)>() +external VARP_t mnn_expr_VARMAP_get( + VARMAP_t self, + ffi.Pointer key, ); -/// ZLIB client - used by PNG, available for other purposes -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, ffi.Int, ffi.Int, ffi.Pointer)>() -external ffi.Pointer stbi_zlib_decode_malloc_guesssize( - ffi.Pointer buffer, - int len, - int initial_size, - ffi.Pointer outlen, +@ffi.Native)>() +external VARP_t mnn_expr_VARMAP_get_ref( + VARMAP_t self, + ffi.Pointer key, ); -@ffi.Native< - ffi.Pointer Function(ffi.Pointer, ffi.Int, ffi.Int, - ffi.Pointer, ffi.Int)>() -external ffi.Pointer stbi_zlib_decode_malloc_guesssize_headerflag( - ffi.Pointer buffer, - int len, - int initial_size, - ffi.Pointer outlen, - int parse_header, +@ffi.Native> Function(VARMAP_t)>() +external ffi.Pointer> mnn_expr_VARMAP_keys( + VARMAP_t self, ); -@ffi.Native< - ffi.Int Function( - ffi.Pointer, ffi.Int, ffi.Pointer, ffi.Int)>() -external int stbi_zlib_decode_noheader_buffer( - ffi.Pointer obuffer, - int olen, - ffi.Pointer ibuffer, - int ilen, +@ffi.Native, VARP_t)>() +external void mnn_expr_VARMAP_set( + VARMAP_t self, + ffi.Pointer key, + VARP_t value, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, ffi.Int, ffi.Pointer)>() -external ffi.Pointer stbi_zlib_decode_noheader_malloc( - ffi.Pointer buffer, - int len, - ffi.Pointer outlen, +@ffi.Native() +external int mnn_expr_VARMAP_size( + VARMAP_t self, ); -/// This builds the samplers and does one allocation -@ffi.Native)>() -external int stbir_build_samplers( - ffi.Pointer resize, +@ffi.Native, ffi.Int)>() +external bool mnn_expr_VARP_copyToDevicePtr( + VARP_t self, + ffi.Pointer devicePtr, + int memoryType, ); -/// This will build samplers for threading. -/// You can pass in the number of threads you'd like to use (try_splits). -/// It returns the number of splits (threads) that you can call it with. -/// It might be less if the image resize can't be split up that many ways. -@ffi.Native, ffi.Int)>() -external int stbir_build_samplers_with_splits( - ffi.Pointer resize, - int try_splits, +@ffi.Native() +external VARP_t mnn_expr_VARP_create_VARP( + VARP_t other, ); -/// You MUST call this, if you call stbir_build_samplers or stbir_build_samplers_with_splits -@ffi.Native)>() -external void stbir_free_samplers( - ffi.Pointer resize, +/// MNN::Express::VARP +@ffi.Native() +external VARP_t mnn_expr_VARP_create_empty(); + +@ffi.Native() +external bool mnn_expr_VARP_fix( + VARP_t self, + int type, ); -/// medium api -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.UnsignedInt, - ffi.UnsignedInt, - ffi.UnsignedInt, - ffi.UnsignedInt)>(symbol: 'stbir_resize') -external ffi.Pointer _stbir_resize( - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - int pixel_layout, - int data_type, - int edge, - int filter, +@ffi.Native)>() +external void mnn_expr_VARP_free( + ffi.Pointer self, ); -ffi.Pointer stbir_resize( - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - StbirPixelLayout pixel_layout, - StbirDataType data_type, - StbirEdge edge, - StbirFilter filter, -) => - _stbir_resize( - input_pixels, - input_w, - input_h, - input_stride_in_bytes, - output_pixels, - output_w, - output_h, - output_stride_in_bytes, - pixel_layout.value, - data_type.value, - edge.value, - filter.value, - ); +@ffi.Native Function(VARP_t)>() +external ffi.Pointer mnn_expr_VARP_getExpr( + VARP_t self, +); -/// And this is the main function to perform the resize synchronously on one thread. -@ffi.Native)>() -external int stbir_resize_extended( - ffi.Pointer resize, +@ffi.Native Function(VARP_t)>() +external ffi.Pointer mnn_expr_VARP_getInfo( + VARP_t self, ); -/// Usually, you will always call stbir_resize_split with split_start as the thread_index -/// and "1" for the split_count. -/// But, if you have a weird situation where you MIGHT want 8 threads, but sometimes -/// only 4 threads, you can use 0,2,4,6 for the split_start's and use "2" for the -/// split_count each time to turn in into a 4 thread resize. (This is unusual). -@ffi.Native, ffi.Int, ffi.Int)>() -external int stbir_resize_extended_split( - ffi.Pointer resize, - int split_start, - int split_count, +@ffi.Native Function(VARP_t)>() +external ffi.Pointer mnn_expr_VARP_getName( + VARP_t self, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.UnsignedInt)>(symbol: 'stbir_resize_float_linear') -external ffi.Pointer _stbir_resize_float_linear( - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - int pixel_type, +@ffi.Native() +external mnn_tensor_t mnn_expr_VARP_getTensor( + VARP_t self, ); -ffi.Pointer stbir_resize_float_linear( - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - StbirPixelLayout pixel_type, -) => - _stbir_resize_float_linear( - input_pixels, - input_w, - input_h, - input_stride_in_bytes, - output_pixels, - output_w, - output_h, - output_stride_in_bytes, - pixel_type.value, - ); +@ffi.Native() +external bool mnn_expr_VARP_input( + VARP_t self, + VARP_t src, +); -/// First off, you must ALWAYS call stbir_resize_init on your resize structure before any of the other calls! +@ffi.Native() +external int mnn_expr_VARP_linkNumber( + VARP_t self, +); + +@ffi.Native() +external VARP_t mnn_expr_VARP_mean( + VARP_t self, + VecI32 dims, +); + +@ffi.Native() +external VARP_t mnn_expr_VARP_op_add( + VARP_t self, + VARP_t other, +); + +@ffi.Native() +external void mnn_expr_VARP_op_assign( + VARP_t self, + VARP_t other, +); + +@ffi.Native() +external VARP_t mnn_expr_VARP_op_div( + VARP_t self, + VARP_t other, +); + +@ffi.Native() +external bool mnn_expr_VARP_op_eqeq( + VARP_t self, + VARP_t other, +); + +@ffi.Native() +external bool mnn_expr_VARP_op_less( + VARP_t self, + VARP_t other, +); + +@ffi.Native() +external bool mnn_expr_VARP_op_lessequal( + VARP_t self, + VARP_t other, +); + +@ffi.Native() +external VARP_t mnn_expr_VARP_op_mul( + VARP_t self, + VARP_t other, +); + +@ffi.Native() +external VARP_t mnn_expr_VARP_op_sub( + VARP_t self, + VARP_t other, +); + +@ffi.Native Function(VARP_t)>() +external ffi.Pointer mnn_expr_VARP_readMap( + VARP_t self, +); + +@ffi.Native() +external bool mnn_expr_VARP_resize( + VARP_t self, + VecI32 dims, +); + +@ffi.Native, ffi.Int)>() +external bool mnn_expr_VARP_setDevicePtr( + VARP_t self, + ffi.Pointer devicePtr, + int memoryType, +); + +@ffi.Native() +external void mnn_expr_VARP_setExpr( + VARP_t self, + EXPRP_t expr, + int index, +); + +/// MNN::Express::Variable +@ffi.Native)>() +external void mnn_expr_VARP_setName( + VARP_t self, + ffi.Pointer name, +); + +@ffi.Native() +external void mnn_expr_VARP_setOrder( + VARP_t self, + int format, +); + +@ffi.Native() +external void mnn_expr_VARP_static_compute( + VecVARP_t vars, + bool forceCPU, +); + +@ffi.Native() +external VARP_t mnn_expr_VARP_static_create_EXPRP( + EXPRP_t expr, + int index, +); + +@ffi.Native)>() +external VecVARP_t mnn_expr_VARP_static_load( + ffi.Pointer fileName, +); + +@ffi.Native, ffi.Size)>() +external VecVARP_t mnn_expr_VARP_static_loadBuffer( + ffi.Pointer buffer, + int length, +); + +@ffi.Native)>() +external VARMAP_t mnn_expr_VARP_static_loadMap( + ffi.Pointer fileName, +); + +@ffi.Native, ffi.Size)>() +external VARMAP_t mnn_expr_VARP_static_loadMapBuffer( + ffi.Pointer buffer, + int length, +); + +@ffi.Native() +external void mnn_expr_VARP_static_prepareCompute( + VecVARP_t vars, + bool forceCPU, +); + +@ffi.Native() +external void mnn_expr_VARP_static_replace( + VARP_t dst, + VARP_t src, +); + +/// MNN_C_API void mnn_expr_VARP_static_getExecuteOrder(VecVARP_t output); +@ffi.Native)>() +external void mnn_expr_VARP_static_save( + VecVARP_t vars, + ffi.Pointer fileName, +); + +@ffi.Native() +external VecI8 mnn_expr_VARP_static_saveBytes( + VecVARP_t vars, +); + +@ffi.Native() +external void mnn_expr_VARP_static_saveNet( + VecVARP_t vars, + Net_t dest, +); + +@ffi.Native() +external VARP_t mnn_expr_VARP_sum( + VARP_t self, + VecI32 dims, +); + +@ffi.Native() +external VecWeakEXPRP_t mnn_expr_VARP_toExprs( + VARP_t self, +); + +@ffi.Native() +external void mnn_expr_VARP_unMap( + VARP_t self, +); + +@ffi.Native Function(VARP_t)>() +external ffi.Pointer mnn_expr_VARP_writeMap( + VARP_t self, +); + +@ffi.Native() +external void mnn_expr_VARP_writeScaleMap( + VARP_t self, + double scaleValue, + double zeroPoint, +); + +@ffi.Native)>() +external void mnn_expr_Variable_Info_free( + ffi.Pointer self, +); + +@ffi.Native() +external VARP_t mnn_expr_VecVARP_at( + VecVARP_t self, + int i, +); + +@ffi.Native() +external VARP_t mnn_expr_VecVARP_at_ref( + VecVARP_t self, + int i, +); + +@ffi.Native() +external VecVARP_t mnn_expr_VecVARP_create( + int length, + VARP_t value, +); + +@ffi.Native)>() +external void mnn_expr_VecVARP_free( + ffi.Pointer self, +); + +@ffi.Native() +external void mnn_expr_VecVARP_push_back( + VecVARP_t self, + VARP_t value, +); + +@ffi.Native() +external void mnn_expr_VecVARP_set( + VecVARP_t self, + int i, + VARP_t value, +); + +@ffi.Native() +external int mnn_expr_VecVARP_size( + VecVARP_t self, +); + +@ffi.Native() +external EXPRP_t mnn_expr_VecWeakEXPRP_at( + VecWeakEXPRP_t self, + int i, +); + +@ffi.Native)>() +external void mnn_expr_VecWeakEXPRP_free( + ffi.Pointer self, +); + +@ffi.Native() +external void mnn_expr_VecWeakEXPRP_push_back( + VecWeakEXPRP_t self, + EXPRP_t value, +); + +@ffi.Native() +external void mnn_expr_VecWeakEXPRP_set( + VecWeakEXPRP_t self, + int i, + EXPRP_t value, +); + +@ffi.Native() +external int mnn_expr_VecWeakEXPRP_size( + VecWeakEXPRP_t self, +); + +/// MNN_PUBLIC VARP _ImageProcess(VARP input, CV::ImageProcess::Config config, CV::Matrix matrix, int +/// oh, int ow, int oc, int dtype, uint8_t padVal = 0); mnn_expr_VARP_t +/// mnn_expr_ImageProcess(mnn_expr_VARP_t input, CV::ImageProcess::Config config, CV::Matrix matrix, +/// int oh, int ow, int oc, int dtype, uint8_t padVal); +@ffi.Native() +external VARP_t mnn_expr_Where( + VARP_t x, +); + +@ffi.Native() +external VARP_t mnn_expr_ZeroGrad( + VARP_t x, +); + +@ffi.Native() +external VARP_t mnn_expr_ZerosLike( + VARP_t input, +); + +/// @brief Get MNN version +/// @return Version string +@ffi.Native Function()>() +external ffi.Pointer mnn_get_version(); + +/// @brief Get biz code from interpreter +/// @param self Interpreter instance +/// @return Biz code string or NULL if failed +@ffi.Native Function(mnn_interpreter_t)>(isLeaf: true) +external ffi.Pointer mnn_interpreter_biz_code( + mnn_interpreter_t self, +); + +/// @brief Create interpreter from buffer +/// @param buffer Model data buffer +/// @param size Buffer size +/// @param callback Callback function to be called after creation +/// @return Interpreter instance or NULL if failed @ffi.Native< - ffi.Void Function( - ffi.Pointer, - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.UnsignedInt, - ffi.UnsignedInt)>(symbol: 'stbir_resize_init') -external void _stbir_resize_init( - ffi.Pointer resize, - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - int pixel_layout, - int data_type, + mnn_interpreter_t Function( + ffi.Pointer, ffi.Size, mnn_callback_0)>() +external mnn_interpreter_t mnn_interpreter_create_from_buffer( + ffi.Pointer buffer, + int size, + mnn_callback_0 callback, ); -void stbir_resize_init( - ffi.Pointer resize, - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - StbirPixelLayout pixel_layout, - StbirDataType data_type, -) => - _stbir_resize_init( - resize, - input_pixels, - input_w, - input_h, - input_stride_in_bytes, - output_pixels, - output_w, - output_h, - output_stride_in_bytes, - pixel_layout.value, - data_type.value, - ); +/// @brief Create interpreter from file +/// @param file_path Path to model file +/// @param callback Callback function to be called after creation +/// @return Interpreter instance or NULL if failed +@ffi.Native, mnn_callback_0)>() +external mnn_interpreter_t mnn_interpreter_create_from_file( + ffi.Pointer file_path, + mnn_callback_0 callback, +); +/// @brief Create runtime info +/// @param configs Schedule config array +/// @param count Config count +/// @return Runtime info instance @ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.UnsignedInt)>(symbol: 'stbir_resize_uint8_linear') -external ffi.Pointer _stbir_resize_uint8_linear( - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - int pixel_type, + mnn_runtime_info_t Function(ffi.Pointer, ffi.Size)>() +external mnn_runtime_info_t mnn_interpreter_create_runtime( + ffi.Pointer configs, + int count, +); + +/// @brief Create session with config +/// @param self Interpreter instance +/// @param config Schedule config +/// @param callback Callback function to be called after creation +/// @return Session instance or NULL if failed +@ffi.Native< + mnn_session_t Function(mnn_interpreter_t, + ffi.Pointer, mnn_callback_0)>() +external mnn_session_t mnn_interpreter_create_session( + mnn_interpreter_t self, + ffi.Pointer config, + mnn_callback_0 callback, +); + +/// @brief Create session with runtime info +/// @param self Interpreter instance +/// @param config Schedule config +/// @param runtime Runtime info +/// @param callback Callback function to be called after creation +/// @return Session instance or NULL if failed +@ffi.Native< + mnn_session_t Function( + mnn_interpreter_t, + ffi.Pointer, + mnn_runtime_info_t, + mnn_callback_0)>() +external mnn_session_t mnn_interpreter_create_session_with_runtime( + mnn_interpreter_t self, + ffi.Pointer config, + mnn_runtime_info_t runtime, + mnn_callback_0 callback, +); + +/// @brief Destroy interpreter instance +/// @param self Interpreter to destroy +@ffi.Native() +external void mnn_interpreter_destroy( + mnn_interpreter_t self, +); + +/// @brief Get backend type +/// @param self Interpreter instance +/// @param session Session +/// @return Backend type +@ffi.Native< + mnn_backend_t Function(mnn_interpreter_t, mnn_session_t, mnn_tensor_t)>() +external mnn_backend_t mnn_interpreter_get_backend( + mnn_interpreter_t self, + mnn_session_t session, + mnn_tensor_t tensor, +); + +/// @brief Get model buffer +/// @param self Interpreter instance +/// @param buffer Output parameter to receive pointer to model data +/// @return Size of model data in bytes, or 0 if failed +@ffi.Native< + ffi.Size Function(mnn_interpreter_t, ffi.Pointer>)>() +external int mnn_interpreter_get_model_buffer( + mnn_interpreter_t self, + ffi.Pointer> buffer, +); + +/// @brief Get model version +/// @param self Interpreter instance +/// @return Version string or NULL if failed +@ffi.Native Function(mnn_interpreter_t)>(isLeaf: true) +external ffi.Pointer mnn_interpreter_get_model_version( + mnn_interpreter_t self, +); + +/// @brief Get session info +/// @param self Interpreter instance +/// @param session Session +/// @param info Output parameter for session info +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, ffi.Int, + ffi.Pointer)>(symbol: 'mnn_interpreter_get_session_info') +external int _mnn_interpreter_get_session_info( + mnn_interpreter_t self, + mnn_session_t session, + int session_info_code, + ffi.Pointer info, +); + +ErrorCode mnn_interpreter_get_session_info( + mnn_interpreter_t self, + mnn_session_t session, + int session_info_code, + ffi.Pointer info, +) => + ErrorCode.fromValue(_mnn_interpreter_get_session_info( + self, + session, + session_info_code, + info, + )); + +/// @brief Get input tensor by name +/// @param self Interpreter instance +/// @param session Session +/// @param name Tensor name (NULL for first input) +/// @return Tensor instance or NULL if failed +@ffi.Native< + mnn_tensor_t Function( + mnn_interpreter_t, mnn_session_t, ffi.Pointer)>() +external mnn_tensor_t mnn_interpreter_get_session_input( + mnn_interpreter_t self, + mnn_session_t session, + ffi.Pointer name, +); + +/// @brief Get all input tensors from session +/// @param self Interpreter instance +/// @param session Session +/// @param tensors Output parameter for tensor array +/// @param count Output parameter for tensor count +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function( + mnn_interpreter_t, + mnn_session_t, + ffi.Pointer>, + ffi.Pointer>>, + ffi.Pointer)>(symbol: 'mnn_interpreter_get_session_input_all') +external int _mnn_interpreter_get_session_input_all( + mnn_interpreter_t self, + mnn_session_t session, + ffi.Pointer> tensors, + ffi.Pointer>> names, + ffi.Pointer count, +); + +ErrorCode mnn_interpreter_get_session_input_all( + mnn_interpreter_t self, + mnn_session_t session, + ffi.Pointer> tensors, + ffi.Pointer>> names, + ffi.Pointer count, +) => + ErrorCode.fromValue(_mnn_interpreter_get_session_input_all( + self, + session, + tensors, + names, + count, + )); + +/// @brief Get output tensor by name +/// @param self Interpreter instance +/// @param session Session +/// @param name Tensor name (NULL for first output) +/// @return Tensor instance or NULL if failed +@ffi.Native< + mnn_tensor_t Function( + mnn_interpreter_t, mnn_session_t, ffi.Pointer)>() +external mnn_tensor_t mnn_interpreter_get_session_output( + mnn_interpreter_t self, + mnn_session_t session, + ffi.Pointer name, +); + +/// @brief Get all output tensors from session +/// @param self Interpreter instance +/// @param session Session +/// @param tensors Output parameter for tensor array +/// @param count Output parameter for tensor count +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function( + mnn_interpreter_t, + mnn_session_t, + ffi.Pointer>, + ffi.Pointer>>, + ffi.Pointer)>( + symbol: 'mnn_interpreter_get_session_output_all') +external int _mnn_interpreter_get_session_output_all( + mnn_interpreter_t self, + mnn_session_t session, + ffi.Pointer> tensors, + ffi.Pointer>> names, + ffi.Pointer count, +); + +ErrorCode mnn_interpreter_get_session_output_all( + mnn_interpreter_t self, + mnn_session_t session, + ffi.Pointer> tensors, + ffi.Pointer>> names, + ffi.Pointer count, +) => + ErrorCode.fromValue(_mnn_interpreter_get_session_output_all( + self, + session, + tensors, + names, + count, + )); + +/// @brief Release model +/// @param self Interpreter instance +@ffi.Native() +external void mnn_interpreter_release_model( + mnn_interpreter_t self, +); + +/// @brief Release session +/// @param self Interpreter instance +/// @param session Session to release +/// @param callback Callback function to be called after release +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, + mnn_callback_0)>(symbol: 'mnn_interpreter_release_session') +external int _mnn_interpreter_release_session( + mnn_interpreter_t self, + mnn_session_t session, + mnn_callback_0 callback, +); + +ErrorCode mnn_interpreter_release_session( + mnn_interpreter_t self, + mnn_session_t session, + mnn_callback_0 callback, +) => + ErrorCode.fromValue(_mnn_interpreter_release_session( + self, + session, + callback, + )); + +/// @brief Resize session +/// @param self Interpreter instance +/// @param session Session to resize +/// @param callback Callback function to be called after resize +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, + mnn_callback_0)>(symbol: 'mnn_interpreter_resize_session') +external int _mnn_interpreter_resize_session( + mnn_interpreter_t self, + mnn_session_t session, + mnn_callback_0 callback, +); + +ErrorCode mnn_interpreter_resize_session( + mnn_interpreter_t self, + mnn_session_t session, + mnn_callback_0 callback, +) => + ErrorCode.fromValue(_mnn_interpreter_resize_session( + self, + session, + callback, + )); + +/// @brief Resize tensor +/// @param tensor Tensor to resize +/// @param dims New dimensions array +/// @param dim_count Dimension count +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function(mnn_interpreter_t, mnn_tensor_t, + ffi.Pointer, ffi.Int)>(symbol: 'mnn_interpreter_resize_tensor') +external int _mnn_interpreter_resize_tensor( + mnn_interpreter_t self, + mnn_tensor_t tensor, + ffi.Pointer dims, + int dim_count, +); + +ErrorCode mnn_interpreter_resize_tensor( + mnn_interpreter_t self, + mnn_tensor_t tensor, + ffi.Pointer dims, + int dim_count, +) => + ErrorCode.fromValue(_mnn_interpreter_resize_tensor( + self, + tensor, + dims, + dim_count, + )); + +@ffi.Native< + ffi.UnsignedInt Function(mnn_interpreter_t, mnn_tensor_t, ffi.Int, ffi.Int, + ffi.Int, ffi.Int)>(symbol: 'mnn_interpreter_resize_tensor_1') +external int _mnn_interpreter_resize_tensor_1( + mnn_interpreter_t self, + mnn_tensor_t tensor, + int batch, + int channel, + int height, + int width, +); + +ErrorCode mnn_interpreter_resize_tensor_1( + mnn_interpreter_t self, + mnn_tensor_t tensor, + int batch, + int channel, + int height, + int width, +) => + ErrorCode.fromValue(_mnn_interpreter_resize_tensor_1( + self, + tensor, + batch, + channel, + height, + width, + )); + +/// @brief Run session +/// @param self Interpreter instance +/// @param session Session to run +/// @param callback Callback function to be called after run +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, + mnn_callback_0)>(symbol: 'mnn_interpreter_run_session') +external int _mnn_interpreter_run_session( + mnn_interpreter_t self, + mnn_session_t session, + mnn_callback_0 callback, +); + +ErrorCode mnn_interpreter_run_session( + mnn_interpreter_t self, + mnn_session_t session, + mnn_callback_0 callback, +) => + ErrorCode.fromValue(_mnn_interpreter_run_session( + self, + session, + callback, + )); + +/// @brief Set cache file for interpreter +/// @param self Interpreter instance +/// @param cache_file Cache file path +/// @param key_size Key size +@ffi.Native< + ffi.Void Function(mnn_interpreter_t, ffi.Pointer, ffi.Size)>() +external void mnn_interpreter_set_cache_file( + mnn_interpreter_t self, + ffi.Pointer cache_file, + int key_size, +); + +/// @brief Set external file for interpreter +/// @param self Interpreter instance +/// @param file External file path +/// @param flag Flag value +@ffi.Native< + ffi.Void Function(mnn_interpreter_t, ffi.Pointer, ffi.Size)>() +external void mnn_interpreter_set_external_file( + mnn_interpreter_t self, + ffi.Pointer file, + int flag, +); + +/// @brief Set session hint +/// @param self Interpreter instance +/// @param mode Hint mode +/// @param value Hint value +@ffi.Native() +external void mnn_interpreter_set_session_hint( + mnn_interpreter_t self, + int mode, + int value, +); + +/// @brief Set session mode +/// @param self Interpreter instance +/// @param mode Session mode +@ffi.Native() +external void mnn_interpreter_set_session_mode( + mnn_interpreter_t self, + int mode, +); + +/// @brief Update cache file +/// @param self Interpreter instance +/// @param session Session +/// @param flag Flag value +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function(mnn_interpreter_t, mnn_session_t, ffi.Int)>( + symbol: 'mnn_interpreter_update_cache_file') +external int _mnn_interpreter_update_cache_file( + mnn_interpreter_t self, + mnn_session_t session, + int flag, +); + +ErrorCode mnn_interpreter_update_cache_file( + mnn_interpreter_t self, + mnn_session_t session, + int flag, +) => + ErrorCode.fromValue(_mnn_interpreter_update_cache_file( + self, + session, + flag, + )); + +/// @brief Update session to model +/// @param self Interpreter instance +/// @param session Session +/// @return Error code +@ffi.Native( + symbol: 'mnn_interpreter_update_session_to_model') +external int _mnn_interpreter_update_session_to_model( + mnn_interpreter_t self, + mnn_session_t session, +); + +ErrorCode mnn_interpreter_update_session_to_model( + mnn_interpreter_t self, + mnn_session_t session, +) => + ErrorCode.fromValue(_mnn_interpreter_update_session_to_model( + self, + session, + )); + +/// @brief Get uuid from interpreter +/// @param self Interpreter instance +/// @return Uuid string or NULL if failed +@ffi.Native Function(mnn_interpreter_t)>(isLeaf: true) +external ffi.Pointer mnn_interpreter_uuid( + mnn_interpreter_t self, +); + +/// @brief Destroy runtime info +/// @param runtime Runtime info to destroy +@ffi.Native() +external void mnn_runtime_info_destroy( + mnn_runtime_info_t runtime, +); + +/// @brief Get tensor batch +/// @param self Tensor +/// @return Batch +@ffi.Native(isLeaf: true) +external int mnn_tensor_batch( + mnn_tensor_t self, +); + +/// @brief Get buffer +/// @param self Tensor +/// @return Buffer pointer +@ffi.Native Function(mnn_tensor_t)>(isLeaf: true) +external ffi.Pointer mnn_tensor_buffer( + mnn_tensor_t self, +); + +/// @brief Get tensor channel +/// @param self Tensor +/// @return Channel +@ffi.Native(isLeaf: true) +external int mnn_tensor_channel( + mnn_tensor_t self, +); + +/// @brief Clone tensor +/// @param src Source tensor +/// @param deep_copy Whether to perform deep copy +/// @return Cloned tensor or NULL if failed +@ffi.Native() +external mnn_tensor_t mnn_tensor_clone( + mnn_tensor_t src, + bool deep_copy, +); + +/// @brief Copy data from host tensor +/// @param self Target tensor +/// @param host_tensor Source tensor +/// @return Error code +@ffi.Native( + symbol: 'mnn_tensor_copy_from_host') +external int _mnn_tensor_copy_from_host( + mnn_tensor_t self, + mnn_tensor_t host_tensor, +); + +ErrorCode mnn_tensor_copy_from_host( + mnn_tensor_t self, + mnn_tensor_t host_tensor, +) => + ErrorCode.fromValue(_mnn_tensor_copy_from_host( + self, + host_tensor, + )); + +/// @brief Copy data to host tensor +/// @param self Source tensor +/// @param host_tensor Target tensor +/// @return Error code +@ffi.Native( + symbol: 'mnn_tensor_copy_to_host') +external int _mnn_tensor_copy_to_host( + mnn_tensor_t self, + mnn_tensor_t host_tensor, +); + +ErrorCode mnn_tensor_copy_to_host( + mnn_tensor_t self, + mnn_tensor_t host_tensor, +) => + ErrorCode.fromValue(_mnn_tensor_copy_to_host( + self, + host_tensor, + )); + +/// @brief Create tensor with dimension size and type +/// @param dim_size Dimension size +/// @param type Dimension type +/// @return Tensor instance or NULL if failed +@ffi.Native( + symbol: 'mnn_tensor_create') +external mnn_tensor_t _mnn_tensor_create( + int dim_size, + int type, +); + +mnn_tensor_t mnn_tensor_create( + int dim_size, + DimensionType type, +) => + _mnn_tensor_create( + dim_size, + type.value, + ); + +/// @brief Create device tensor +/// @param shape Tensor shape array +/// @param shape_size Shape array size +/// @param type Data type +/// @param dim_type Dimension type +/// @return Tensor instance or NULL if failed +@ffi.Native< + mnn_tensor_t Function(ffi.Pointer, ffi.Int, halide_type_c_t, + ffi.UnsignedInt)>(symbol: 'mnn_tensor_create_device') +external mnn_tensor_t _mnn_tensor_create_device( + ffi.Pointer shape, + int shape_size, + halide_type_c_t type, + int dim_type, +); + +mnn_tensor_t mnn_tensor_create_device( + ffi.Pointer shape, + int shape_size, + halide_type_c_t type, + DimensionType dim_type, +) => + _mnn_tensor_create_device( + shape, + shape_size, + type, + dim_type.value, + ); + +/// @brief Create tensor with same shape as given tensor +/// @param self Shape provider +/// @param type Dimension type +/// @param alloc_memory Whether allocate memory +/// @return Tensor instance or NULL if failed +@ffi.Native( + symbol: 'mnn_tensor_create_from_tensor') +external mnn_tensor_t _mnn_tensor_create_from_tensor( + mnn_tensor_t self, + int type, + bool alloc_memory, +); + +mnn_tensor_t mnn_tensor_create_from_tensor( + mnn_tensor_t self, + DimensionType type, + bool alloc_memory, +) => + _mnn_tensor_create_from_tensor( + self, + type.value, + alloc_memory, + ); + +/// @brief Create tensor with data +/// @param shape Tensor shape array +/// @param shape_size Shape array size +/// @param type Data type +/// @param data Data pointer +/// @param dim_type Dimension type +/// @return Tensor instance or NULL if failed +@ffi.Native< + mnn_tensor_t Function( + ffi.Pointer, + ffi.Int, + halide_type_c_t, + ffi.Pointer, + ffi.UnsignedInt)>(symbol: 'mnn_tensor_create_with_data') +external mnn_tensor_t _mnn_tensor_create_with_data( + ffi.Pointer shape, + int shape_size, + halide_type_c_t type, + ffi.Pointer data, + int dim_type, +); + +mnn_tensor_t mnn_tensor_create_with_data( + ffi.Pointer shape, + int shape_size, + halide_type_c_t type, + ffi.Pointer data, + DimensionType dim_type, +) => + _mnn_tensor_create_with_data( + shape, + shape_size, + type, + data, + dim_type.value, + ); + +/// @brief Destroy tensor +/// @param tensor Tensor to destroy +@ffi.Native(isLeaf: true) +external void mnn_tensor_destroy( + mnn_tensor_t tensor, +); + +/// @brief Get device ID +/// @param self Tensor +/// @return Device ID +@ffi.Native(isLeaf: true) +external int mnn_tensor_device_id( + mnn_tensor_t self, +); + +/// @brief Get tensor dimensions +/// @param self Tensor +/// @return Dimension count +@ffi.Native(isLeaf: true) +external int mnn_tensor_dimensions( + mnn_tensor_t self, +); + +/// @brief Get tensor element count +/// @param self Tensor +/// @return Element count +@ffi.Native(isLeaf: true) +external int mnn_tensor_element_size( + mnn_tensor_t self, +); + +/// @brief Get dimension type +/// @param self Tensor +/// @return Dimension type +@ffi.Native( + symbol: 'mnn_tensor_get_dimension_type', isLeaf: true) +external int _mnn_tensor_get_dimension_type( + mnn_tensor_t self, +); + +DimensionType mnn_tensor_get_dimension_type( + mnn_tensor_t self, +) => + DimensionType.fromValue(_mnn_tensor_get_dimension_type( + self, + )); + +/// @brief Get handle data type +/// @param self Tensor +/// @return Handle data type +@ffi.Native( + symbol: 'mnn_tensor_get_handle_data_type', isLeaf: true) +external int _mnn_tensor_get_handle_data_type( + mnn_tensor_t self, +); + +HandleDataType mnn_tensor_get_handle_data_type( + mnn_tensor_t self, +) => + HandleDataType.fromValue(_mnn_tensor_get_handle_data_type( + self, + )); + +/// @brief Get data type +/// @param self Tensor +/// @return Data type +@ffi.Native Function(mnn_tensor_t)>(isLeaf: true) +external ffi.Pointer mnn_tensor_get_type( + mnn_tensor_t self, +); + +/// @brief Get tensor height +/// @param self Tensor +/// @return Height +@ffi.Native(isLeaf: true) +external int mnn_tensor_height( + mnn_tensor_t self, +); + +/// @brief Get host data pointer +/// @param self Tensor +/// @return Data pointer or NULL +@ffi.Native Function(mnn_tensor_t)>(isLeaf: true) +external ffi.Pointer mnn_tensor_host( + mnn_tensor_t self, +); + +/// @brief Get tensor length +/// @param self Tensor +/// @param index Dimension index +/// @return Length +@ffi.Native(isLeaf: true) +external int mnn_tensor_length( + mnn_tensor_t self, + int index, +); + +/// @brief Map tensor for access +/// @param self Tensor +/// @param mtype Map type +/// @param dtype Dimension type +/// @return Mapped pointer or NULL +@ffi.Native< + ffi.Pointer Function(mnn_tensor_t, ffi.UnsignedInt, + ffi.UnsignedInt)>(symbol: 'mnn_tensor_map', isLeaf: true) +external ffi.Pointer _mnn_tensor_map( + mnn_tensor_t self, + int mtype, + int dtype, +); + +ffi.Pointer mnn_tensor_map( + mnn_tensor_t self, + MapType mtype, + DimensionType dtype, +) => + _mnn_tensor_map( + self, + mtype.value, + dtype.value, + ); + +@ffi.Native() +external void mnn_tensor_print( + mnn_tensor_t self, +); + +@ffi.Native() +external void mnn_tensor_print_shape( + mnn_tensor_t self, +); + +/// @brief Set device pointer +/// @param self Tensor +/// @param device_ptr Device pointer +/// @param memory_type Memory type +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function(mnn_tensor_t, ffi.Pointer, ffi.Int)>( + symbol: 'mnn_tensor_set_device_ptr', isLeaf: true) +external int _mnn_tensor_set_device_ptr( + mnn_tensor_t self, + ffi.Pointer device_ptr, + int memory_type, +); + +ErrorCode mnn_tensor_set_device_ptr( + mnn_tensor_t self, + ffi.Pointer device_ptr, + int memory_type, +) => + ErrorCode.fromValue(_mnn_tensor_set_device_ptr( + self, + device_ptr, + memory_type, + )); + +@ffi.Native< + ffi.UnsignedInt Function( + mnn_tensor_t, + ffi.Int, + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int)>(symbol: 'mnn_tensor_set_image_f32', isLeaf: true) +external int _mnn_tensor_set_image_f32( + mnn_tensor_t self, + int index, + ffi.Pointer data, + int width, + int height, + int channel, +); + +ErrorCode mnn_tensor_set_image_f32( + mnn_tensor_t self, + int index, + ffi.Pointer data, + int width, + int height, + int channel, +) => + ErrorCode.fromValue(_mnn_tensor_set_image_f32( + self, + index, + data, + width, + height, + channel, + )); + +/// @brief Set tensor length +/// @param self Tensor +/// @param index Dimension index +/// @param length Length value +@ffi.Native(isLeaf: true) +external void mnn_tensor_set_length( + mnn_tensor_t self, + int index, + int length, +); + +/// @brief Set tensor stride +/// @param self Tensor +/// @param index Dimension index +/// @param stride Stride value +@ffi.Native(isLeaf: true) +external void mnn_tensor_set_stride( + mnn_tensor_t self, + int index, + int stride, +); + +/// @brief Set data type +/// @param self Tensor +/// @param type Data type +@ffi.Native(isLeaf: true) +external void mnn_tensor_set_type( + mnn_tensor_t self, + int type, +); + +/// @brief Get tensor shape +/// @param self Tensor +/// @param shape Output shape array (must be pre-allocated) +/// @param shape_size Shape array size +/// @return Error code +@ffi.Native< + ffi.UnsignedInt Function(mnn_tensor_t, ffi.Pointer, ffi.Int)>( + symbol: 'mnn_tensor_shape', isLeaf: true) +external int _mnn_tensor_shape( + mnn_tensor_t self, + ffi.Pointer shape, + int shape_size, +); + +ErrorCode mnn_tensor_shape( + mnn_tensor_t self, + ffi.Pointer shape, + int shape_size, +) => + ErrorCode.fromValue(_mnn_tensor_shape( + self, + shape, + shape_size, + )); + +/// @brief Get tensor data size in bytes +/// @param self Tensor +/// @return Size in bytes +@ffi.Native(isLeaf: true) +external int mnn_tensor_size( + mnn_tensor_t self, +); + +/// @brief Get tensor stride +/// @param self Tensor +/// @param index Dimension index +/// @return Stride +@ffi.Native(isLeaf: true) +external int mnn_tensor_stride( + mnn_tensor_t self, + int index, +); + +/// @brief Unmap tensor +/// @param self Tensor +/// @param mtype Map type +/// @param dtype Dimension type +/// @param map_ptr Mapped pointer +@ffi.Native< + ffi.Void Function(mnn_tensor_t, ffi.UnsignedInt, ffi.UnsignedInt, + ffi.Pointer)>(symbol: 'mnn_tensor_unmap', isLeaf: true) +external void _mnn_tensor_unmap( + mnn_tensor_t self, + int mtype, + int dtype, + ffi.Pointer map_ptr, +); + +void mnn_tensor_unmap( + mnn_tensor_t self, + MapType mtype, + DimensionType dtype, + ffi.Pointer map_ptr, +) => + _mnn_tensor_unmap( + self, + mtype.value, + dtype.value, + map_ptr, + ); + +/// @brief Get tensor shape in bytes (unsigned) +/// @param self Tensor +/// @return Size in bytes +@ffi.Native(isLeaf: true) +external int mnn_tensor_usize( + mnn_tensor_t self, +); + +/// @brief Wait for tensor ready +/// @param self Tensor +/// @param mtype Map type +/// @param finish Whether wait for finish +/// @return Error code +@ffi.Native( + symbol: 'mnn_tensor_wait') +external int _mnn_tensor_wait( + mnn_tensor_t self, + int mtype, + bool finish, +); + +ErrorCode mnn_tensor_wait( + mnn_tensor_t self, + MapType mtype, + bool finish, +) => + ErrorCode.fromValue(_mnn_tensor_wait( + self, + mtype.value, + finish, + )); + +/// @brief Get tensor width +/// @param self Tensor +/// @return Width +@ffi.Native(isLeaf: true) +external int mnn_tensor_width( + mnn_tensor_t self, +); + +/// @brief Creates a new timer instance +/// @return Pointer to the newly created timer +@ffi.Native() +external mnn_timer_t mnn_timer_create(); + +/// @brief Gets the current time value from timer +/// @param timer Timer instance to query +/// @return Current time value +@ffi.Native() +external int mnn_timer_current( + mnn_timer_t timer, +); + +/// @brief Destroys a timer instance +/// @param timer Timer instance to destroy +@ffi.Native() +external void mnn_timer_destroy( + mnn_timer_t timer, +); + +/// @brief Gets the duration in microseconds since last reset +/// @param timer Timer instance to query +/// @return Duration in microseconds +@ffi.Native() +external int mnn_timer_duration_us( + mnn_timer_t timer, +); + +/// @brief Resets the timer to current time +/// @param timer Timer instance to reset +@ffi.Native() +external void mnn_timer_reset( + mnn_timer_t timer, +); + +/// indicate whether we should process iphone images back to canonical format, +/// or just pass them through "as-is" +@ffi.Native() +external void stbi_convert_iphone_png_to_rgb( + int flag_true_if_should_convert, +); + +@ffi.Native() +external void stbi_convert_iphone_png_to_rgb_thread( + int flag_true_if_should_convert, +); + +/// get a VERY brief reason for failure +/// on most compilers (and ALL modern mainstream compilers) this is threadsafe +@ffi.Native Function()>() +external ffi.Pointer stbi_failure_reason(); + +@ffi.Native() +external void stbi_flip_vertically_on_write( + int flip_boolean, +); + +@ffi.Native() +external void stbi_hdr_to_ldr_gamma( + double gamma, +); + +@ffi.Native() +external void stbi_hdr_to_ldr_scale( + double scale, +); + +/// free the loaded image -- this is just free() +@ffi.Native)>() +external void stbi_image_free( + ffi.Pointer retval_from_stbi_load, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer)>() +external int stbi_info( + ffi.Pointer filename, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer comp, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer, ffi.Pointer)>() +external int stbi_info_from_callbacks( + ffi.Pointer clbk, + ffi.Pointer user, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer comp, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer)>() +external int stbi_info_from_file( + ffi.Pointer f, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer comp, +); + +/// get image dimensions & components without fully decoding +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Pointer, + ffi.Pointer, ffi.Pointer)>() +external int stbi_info_from_memory( + ffi.Pointer buffer, + int len, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer comp, +); + +@ffi.Native)>() +external int stbi_is_16_bit( + ffi.Pointer filename, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer)>() +external int stbi_is_16_bit_from_callbacks( + ffi.Pointer clbk, + ffi.Pointer user, +); + +@ffi.Native)>() +external int stbi_is_16_bit_from_file( + ffi.Pointer f, +); + +@ffi.Native, ffi.Int)>() +external int stbi_is_16_bit_from_memory( + ffi.Pointer buffer, + int len, +); + +@ffi.Native)>() +external int stbi_is_hdr( + ffi.Pointer filename, +); + +/// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer)>() +external int stbi_is_hdr_from_callbacks( + ffi.Pointer clbk, + ffi.Pointer user, +); + +@ffi.Native)>() +external int stbi_is_hdr_from_file( + ffi.Pointer f, +); + +@ffi.Native, ffi.Int)>() +external int stbi_is_hdr_from_memory( + ffi.Pointer buffer, + int len, +); + +@ffi.Native() +external void stbi_ldr_to_hdr_gamma( + double gamma, +); + +@ffi.Native() +external void stbi_ldr_to_hdr_scale( + double scale, +); + +@ffi.Native< + ffi.Pointer Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer, ffi.Int)>() +external ffi.Pointer stbi_load( + ffi.Pointer filename, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer, ffi.Int)>() +external ffi.Pointer stbi_load_16( + ffi.Pointer filename, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Int)>() +external ffi.Pointer stbi_load_16_from_callbacks( + ffi.Pointer clbk, + ffi.Pointer user, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +/// ///////////////////////////////// +/// +/// 16-bits-per-channel interface +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Int)>() +external ffi.Pointer stbi_load_16_from_memory( + ffi.Pointer buffer, + int len, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Int)>() +external ffi.Pointer stbi_load_from_callbacks( + ffi.Pointer clbk, + ffi.Pointer user, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer, ffi.Int)>() +external ffi.Pointer stbi_load_from_file( + ffi.Pointer f, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer, ffi.Int)>() +external ffi.Pointer stbi_load_from_file_16( + ffi.Pointer f, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +/// ///////////////////////////////// +/// +/// 8-bits-per-channel interface +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Int)>() +external ffi.Pointer stbi_load_from_memory( + ffi.Pointer buffer, + int len, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int, + ffi.Pointer>, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Int)>() +external ffi.Pointer stbi_load_gif_from_memory( + ffi.Pointer buffer, + int len, + ffi.Pointer> delays, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer z, + ffi.Pointer comp, + int req_comp, +); + +@ffi.Native< + ffi.Pointer Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer, ffi.Int)>() +external ffi.Pointer stbi_loadf( + ffi.Pointer filename, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Int)>() +external ffi.Pointer stbi_loadf_from_callbacks( + ffi.Pointer clbk, + ffi.Pointer user, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer, ffi.Int)>() +external ffi.Pointer stbi_loadf_from_file( + ffi.Pointer f, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Int)>() +external ffi.Pointer stbi_loadf_from_memory( + ffi.Pointer buffer, + int len, + ffi.Pointer x, + ffi.Pointer y, + ffi.Pointer channels_in_file, + int desired_channels, +); + +/// flip the image vertically, so the first pixel in the output array is the bottom left +@ffi.Native() +external void stbi_set_flip_vertically_on_load( + int flag_true_if_should_flip, +); + +@ffi.Native() +external void stbi_set_flip_vertically_on_load_thread( + int flag_true_if_should_flip, +); + +/// for image formats that explicitly notate that they have premultiplied alpha, +/// we just return the colors as stored in the file. set this flag to force +/// unpremultiplication. results are undefined if the unpremultiply overflow. +@ffi.Native() +external void stbi_set_unpremultiply_on_load( + int flag_true_if_should_unpremultiply, +); + +/// as above, but only applies to images loaded on the thread that calls the function +/// this function is only available if your compiler supports thread-local variables; +/// calling it will fail to link if your compiler doesn't +@ffi.Native() +external void stbi_set_unpremultiply_on_load_thread( + int flag_true_if_should_unpremultiply, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, + ffi.Pointer)>() +external int stbi_write_bmp( + ffi.Pointer filename, + int w, + int h, + int comp, + ffi.Pointer data, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer, + ffi.Int, ffi.Int, ffi.Int, ffi.Pointer)>() +external int stbi_write_bmp_to_func( + ffi.Pointer func, + ffi.Pointer context, + int w, + int h, + int comp, + ffi.Pointer data, +); + +@ffi.Native() +external int stbi_write_force_png_filter; + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, + ffi.Pointer)>() +external int stbi_write_hdr( + ffi.Pointer filename, + int w, + int h, + int comp, + ffi.Pointer data, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer, + ffi.Int, ffi.Int, ffi.Int, ffi.Pointer)>() +external int stbi_write_hdr_to_func( + ffi.Pointer func, + ffi.Pointer context, + int w, + int h, + int comp, + ffi.Pointer data, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, + ffi.Pointer, ffi.Int)>() +external int stbi_write_jpg( + ffi.Pointer filename, + int x, + int y, + int comp, + ffi.Pointer data, + int quality, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer, + ffi.Int, ffi.Int, ffi.Int, ffi.Pointer, ffi.Int)>() +external int stbi_write_jpg_to_func( + ffi.Pointer func, + ffi.Pointer context, + int x, + int y, + int comp, + ffi.Pointer data, + int quality, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, + ffi.Pointer, ffi.Int)>() +external int stbi_write_png( + ffi.Pointer filename, + int w, + int h, + int comp, + ffi.Pointer data, + int stride_in_bytes, +); + +@ffi.Native() +external int stbi_write_png_compression_level; + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer, + ffi.Int, ffi.Int, ffi.Int, ffi.Pointer, ffi.Int)>() +external int stbi_write_png_to_func( + ffi.Pointer func, + ffi.Pointer context, + int w, + int h, + int comp, + ffi.Pointer data, + int stride_in_bytes, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, + ffi.Pointer)>() +external int stbi_write_tga( + ffi.Pointer filename, + int w, + int h, + int comp, + ffi.Pointer data, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Pointer, + ffi.Int, ffi.Int, ffi.Int, ffi.Pointer)>() +external int stbi_write_tga_to_func( + ffi.Pointer func, + ffi.Pointer context, + int w, + int h, + int comp, + ffi.Pointer data, +); + +@ffi.Native() +external int stbi_write_tga_with_rle; + +@ffi.Native< + ffi.Int Function( + ffi.Pointer, ffi.Int, ffi.Pointer, ffi.Int)>() +external int stbi_zlib_decode_buffer( + ffi.Pointer obuffer, + int olen, + ffi.Pointer ibuffer, + int ilen, +); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, ffi.Int, ffi.Pointer)>() +external ffi.Pointer stbi_zlib_decode_malloc( + ffi.Pointer buffer, + int len, + ffi.Pointer outlen, +); + +/// ZLIB client - used by PNG, available for other purposes +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, ffi.Int, ffi.Int, ffi.Pointer)>() +external ffi.Pointer stbi_zlib_decode_malloc_guesssize( + ffi.Pointer buffer, + int len, + int initial_size, + ffi.Pointer outlen, +); + +@ffi.Native< + ffi.Pointer Function(ffi.Pointer, ffi.Int, ffi.Int, + ffi.Pointer, ffi.Int)>() +external ffi.Pointer stbi_zlib_decode_malloc_guesssize_headerflag( + ffi.Pointer buffer, + int len, + int initial_size, + ffi.Pointer outlen, + int parse_header, +); + +@ffi.Native< + ffi.Int Function( + ffi.Pointer, ffi.Int, ffi.Pointer, ffi.Int)>() +external int stbi_zlib_decode_noheader_buffer( + ffi.Pointer obuffer, + int olen, + ffi.Pointer ibuffer, + int ilen, +); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, ffi.Int, ffi.Pointer)>() +external ffi.Pointer stbi_zlib_decode_noheader_malloc( + ffi.Pointer buffer, + int len, + ffi.Pointer outlen, +); + +/// This builds the samplers and does one allocation +@ffi.Native)>() +external int stbir_build_samplers( + ffi.Pointer resize, +); + +/// This will build samplers for threading. +/// You can pass in the number of threads you'd like to use (try_splits). +/// It returns the number of splits (threads) that you can call it with. +/// It might be less if the image resize can't be split up that many ways. +@ffi.Native, ffi.Int)>() +external int stbir_build_samplers_with_splits( + ffi.Pointer resize, + int try_splits, +); + +/// You MUST call this, if you call stbir_build_samplers or stbir_build_samplers_with_splits +@ffi.Native)>() +external void stbir_free_samplers( + ffi.Pointer resize, +); + +/// medium api +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.UnsignedInt, + ffi.UnsignedInt, + ffi.UnsignedInt, + ffi.UnsignedInt)>(symbol: 'stbir_resize') +external ffi.Pointer _stbir_resize( + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + int pixel_layout, + int data_type, + int edge, + int filter, +); + +ffi.Pointer stbir_resize( + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + StbirPixelLayout pixel_layout, + StbirDataType data_type, + StbirEdge edge, + StbirFilter filter, +) => + _stbir_resize( + input_pixels, + input_w, + input_h, + input_stride_in_bytes, + output_pixels, + output_w, + output_h, + output_stride_in_bytes, + pixel_layout.value, + data_type.value, + edge.value, + filter.value, + ); + +/// And this is the main function to perform the resize synchronously on one thread. +@ffi.Native)>() +external int stbir_resize_extended( + ffi.Pointer resize, +); + +/// Usually, you will always call stbir_resize_split with split_start as the thread_index +/// and "1" for the split_count. +/// But, if you have a weird situation where you MIGHT want 8 threads, but sometimes +/// only 4 threads, you can use 0,2,4,6 for the split_start's and use "2" for the +/// split_count each time to turn in into a 4 thread resize. (This is unusual). +@ffi.Native, ffi.Int, ffi.Int)>() +external int stbir_resize_extended_split( + ffi.Pointer resize, + int split_start, + int split_count, +); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.UnsignedInt)>(symbol: 'stbir_resize_float_linear') +external ffi.Pointer _stbir_resize_float_linear( + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + int pixel_type, +); + +ffi.Pointer stbir_resize_float_linear( + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + StbirPixelLayout pixel_type, +) => + _stbir_resize_float_linear( + input_pixels, + input_w, + input_h, + input_stride_in_bytes, + output_pixels, + output_w, + output_h, + output_stride_in_bytes, + pixel_type.value, + ); + +/// First off, you must ALWAYS call stbir_resize_init on your resize structure before any of the other calls! +@ffi.Native< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.UnsignedInt, + ffi.UnsignedInt)>(symbol: 'stbir_resize_init') +external void _stbir_resize_init( + ffi.Pointer resize, + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + int pixel_layout, + int data_type, +); + +void stbir_resize_init( + ffi.Pointer resize, + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + StbirPixelLayout pixel_layout, + StbirDataType data_type, +) => + _stbir_resize_init( + resize, + input_pixels, + input_w, + input_h, + input_stride_in_bytes, + output_pixels, + output_w, + output_h, + output_stride_in_bytes, + pixel_layout.value, + data_type.value, + ); + +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.UnsignedInt)>(symbol: 'stbir_resize_uint8_linear') +external ffi.Pointer _stbir_resize_uint8_linear( + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + int pixel_type, +); + +ffi.Pointer stbir_resize_uint8_linear( + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + StbirPixelLayout pixel_type, +) => + _stbir_resize_uint8_linear( + input_pixels, + input_w, + input_h, + input_stride_in_bytes, + output_pixels, + output_w, + output_h, + output_stride_in_bytes, + pixel_type.value, + ); + +/// =============================================================== +/// Simple-complexity API +/// +/// If output_pixels is NULL (0), then we will allocate the buffer and return it to you. +/// -------------------------------- +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.Pointer, + ffi.Int, + ffi.Int, + ffi.Int, + ffi.UnsignedInt)>(symbol: 'stbir_resize_uint8_srgb') +external ffi.Pointer _stbir_resize_uint8_srgb( + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + int pixel_type, +); + +ffi.Pointer stbir_resize_uint8_srgb( + ffi.Pointer input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + StbirPixelLayout pixel_type, +) => + _stbir_resize_uint8_srgb( + input_pixels, + input_w, + input_h, + input_stride_in_bytes, + output_pixels, + output_w, + output_h, + output_stride_in_bytes, + pixel_type.value, + ); + +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer, ffi.Int, + ffi.Pointer, ffi.Int)>() +external void stbir_set_buffer_ptrs( + ffi.Pointer resize, + ffi.Pointer input_pixels, + int input_stride_in_bytes, + ffi.Pointer output_pixels, + int output_stride_in_bytes, +); + +/// =============================================================== +/// You can update these parameters any time after resize_init and there is no cost +/// -------------------------------- +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.UnsignedInt, + ffi.UnsignedInt)>(symbol: 'stbir_set_datatypes') +external void _stbir_set_datatypes( + ffi.Pointer resize, + int input_type, + int output_type, +); + +void stbir_set_datatypes( + ffi.Pointer resize, + StbirDataType input_type, + StbirDataType output_type, +) => + _stbir_set_datatypes( + resize, + input_type.value, + output_type.value, + ); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.UnsignedInt, + ffi.UnsignedInt)>(symbol: 'stbir_set_edgemodes') +external int _stbir_set_edgemodes( + ffi.Pointer resize, + int horizontal_edge, + int vertical_edge, +); + +int stbir_set_edgemodes( + ffi.Pointer resize, + StbirEdge horizontal_edge, + StbirEdge vertical_edge, +) => + _stbir_set_edgemodes( + resize, + horizontal_edge.value, + vertical_edge.value, + ); + +@ffi.Native< + ffi.Int Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>() +external int stbir_set_filter_callbacks( + ffi.Pointer resize, + ffi.Pointer horizontal_filter, + ffi.Pointer horizontal_support, + ffi.Pointer vertical_filter, + ffi.Pointer vertical_support, +); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.UnsignedInt, + ffi.UnsignedInt)>(symbol: 'stbir_set_filters') +external int _stbir_set_filters( + ffi.Pointer resize, + int horizontal_filter, + int vertical_filter, +); + +int stbir_set_filters( + ffi.Pointer resize, + StbirFilter horizontal_filter, + StbirFilter vertical_filter, +) => + _stbir_set_filters( + resize, + horizontal_filter.value, + vertical_filter.value, + ); + +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.Double, ffi.Double, + ffi.Double, ffi.Double)>() +external int stbir_set_input_subrect( + ffi.Pointer resize, + double s0, + double t0, + double s1, + double t1, +); + +/// when inputting AND outputting non-premultiplied alpha pixels, we use a slower but higher quality technique +/// that fills the zero alpha pixel's RGB values with something plausible. If you don't care about areas of +/// zero alpha, you can call this function to get about a 25% speed improvement for STBIR_RGBA to STBIR_RGBA +/// types of resizes. +@ffi.Native, ffi.Int)>() +external int stbir_set_non_pm_alpha_speed_over_quality( + ffi.Pointer resize, + int non_pma_alpha_speed_over_quality, +); + +@ffi.Native< + ffi.Int Function( + ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, ffi.Int)>() +external int stbir_set_output_pixel_subrect( + ffi.Pointer resize, + int subx, + int suby, + int subw, + int subh, +); + +@ffi.Native< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>() +external void stbir_set_pixel_callbacks( + ffi.Pointer resize, + ffi.Pointer input_cb, + ffi.Pointer output_cb, +); + +/// =============================================================== +/// If you call any of these functions, you will trigger a sampler rebuild! +/// -------------------------------- +@ffi.Native< + ffi.Int Function(ffi.Pointer, ffi.UnsignedInt, + ffi.UnsignedInt)>(symbol: 'stbir_set_pixel_layouts') +external int _stbir_set_pixel_layouts( + ffi.Pointer resize, + int input_pixel_layout, + int output_pixel_layout, +); + +int stbir_set_pixel_layouts( + ffi.Pointer resize, + StbirPixelLayout input_pixel_layout, + StbirPixelLayout output_pixel_layout, +) => + _stbir_set_pixel_layouts( + resize, + input_pixel_layout.value, + output_pixel_layout.value, + ); + +@ffi.Native< + ffi.Int Function( + ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, ffi.Int)>() +external int stbir_set_pixel_subrect( + ffi.Pointer resize, + int subx, + int suby, + int subw, + int subh, +); + +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer)>() +external void stbir_set_user_data( + ffi.Pointer resize, + ffi.Pointer user_data, +); + +@ffi.Native() +external void std_VecF16_clear( + VecF16 self, +); + +@ffi.Native() +external VecF16 std_VecF16_clone( + VecF16 self, +); + +@ffi.Native Function(VecF16)>() +external ffi.Pointer std_VecF16_data( + VecF16 self, +); + +@ffi.Native() +external void std_VecF16_extend( + VecF16 self, + VecF16 other, +); + +@ffi.Native() +external void std_VecF16_free( + VecF16 self, +); + +@ffi.Native() +external int std_VecF16_get( + VecF16 self, + int index, +); + +@ffi.Native() +external int std_VecF16_length( + VecF16 self, +); + +@ffi.Native() +external VecF16 std_VecF16_new( + int length, +); + +@ffi.Native() +external VecF16 std_VecF16_new_1( + int length, + int val, +); + +@ffi.Native)>() +external VecF16 std_VecF16_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecF16_push_back( + VecF16 self, + int val, +); + +@ffi.Native() +external void std_VecF16_reserve( + VecF16 self, + int new_len, +); + +@ffi.Native() +external void std_VecF16_resize( + VecF16 self, + int new_len, +); + +@ffi.Native() +external void std_VecF16_set( + VecF16 self, + int index, + int val, +); + +@ffi.Native() +external void std_VecF16_shrink_to_fit( + VecF16 self, +); + +@ffi.Native() +external void std_VecF32_clear( + VecF32 self, +); + +@ffi.Native() +external VecF32 std_VecF32_clone( + VecF32 self, +); + +@ffi.Native Function(VecF32)>() +external ffi.Pointer std_VecF32_data( + VecF32 self, +); + +@ffi.Native() +external void std_VecF32_extend( + VecF32 self, + VecF32 other, +); + +@ffi.Native() +external void std_VecF32_free( + VecF32 self, +); + +@ffi.Native() +external double std_VecF32_get( + VecF32 self, + int index, +); + +@ffi.Native() +external int std_VecF32_length( + VecF32 self, +); + +@ffi.Native() +external VecF32 std_VecF32_new( + int length, +); + +@ffi.Native() +external VecF32 std_VecF32_new_1( + int length, + double val, +); + +@ffi.Native)>() +external VecF32 std_VecF32_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecF32_push_back( + VecF32 self, + double val, +); + +@ffi.Native() +external void std_VecF32_reserve( + VecF32 self, + int new_len, +); + +@ffi.Native() +external void std_VecF32_resize( + VecF32 self, + int new_len, +); + +@ffi.Native() +external void std_VecF32_set( + VecF32 self, + int index, + double val, +); + +@ffi.Native() +external void std_VecF32_shrink_to_fit( + VecF32 self, +); + +@ffi.Native() +external void std_VecF64_clear( + VecF64 self, +); + +@ffi.Native() +external VecF64 std_VecF64_clone( + VecF64 self, +); + +@ffi.Native Function(VecF64)>() +external ffi.Pointer std_VecF64_data( + VecF64 self, +); + +@ffi.Native() +external void std_VecF64_extend( + VecF64 self, + VecF64 other, +); + +@ffi.Native() +external void std_VecF64_free( + VecF64 self, +); + +@ffi.Native() +external double std_VecF64_get( + VecF64 self, + int index, +); + +@ffi.Native() +external int std_VecF64_length( + VecF64 self, +); + +@ffi.Native() +external VecF64 std_VecF64_new( + int length, +); + +@ffi.Native() +external VecF64 std_VecF64_new_1( + int length, + double val, +); + +@ffi.Native)>() +external VecF64 std_VecF64_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecF64_push_back( + VecF64 self, + double val, +); + +@ffi.Native() +external void std_VecF64_reserve( + VecF64 self, + int new_len, +); + +@ffi.Native() +external void std_VecF64_resize( + VecF64 self, + int new_len, +); + +@ffi.Native() +external void std_VecF64_set( + VecF64 self, + int index, + double val, +); + +@ffi.Native() +external void std_VecF64_shrink_to_fit( + VecF64 self, +); + +@ffi.Native() +external void std_VecI16_clear( + VecI16 self, +); + +@ffi.Native() +external VecI16 std_VecI16_clone( + VecI16 self, +); + +@ffi.Native Function(VecI16)>() +external ffi.Pointer std_VecI16_data( + VecI16 self, +); + +@ffi.Native() +external void std_VecI16_extend( + VecI16 self, + VecI16 other, +); + +@ffi.Native() +external void std_VecI16_free( + VecI16 self, +); + +@ffi.Native() +external int std_VecI16_get( + VecI16 self, + int index, +); + +@ffi.Native() +external int std_VecI16_length( + VecI16 self, +); + +@ffi.Native() +external VecI16 std_VecI16_new( + int length, +); + +@ffi.Native() +external VecI16 std_VecI16_new_1( + int length, + int val, +); + +@ffi.Native)>() +external VecI16 std_VecI16_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecI16_push_back( + VecI16 self, + int val, +); + +@ffi.Native() +external void std_VecI16_reserve( + VecI16 self, + int new_len, +); + +@ffi.Native() +external void std_VecI16_resize( + VecI16 self, + int new_len, +); + +@ffi.Native() +external void std_VecI16_set( + VecI16 self, + int index, + int val, +); + +@ffi.Native() +external void std_VecI16_shrink_to_fit( + VecI16 self, +); + +@ffi.Native() +external void std_VecI32_clear( + VecI32 self, +); + +@ffi.Native() +external VecI32 std_VecI32_clone( + VecI32 self, +); + +@ffi.Native Function(VecI32)>() +external ffi.Pointer std_VecI32_data( + VecI32 self, +); + +@ffi.Native() +external void std_VecI32_extend( + VecI32 self, + VecI32 other, +); + +@ffi.Native() +external void std_VecI32_free( + VecI32 self, +); + +@ffi.Native() +external int std_VecI32_get( + VecI32 self, + int index, +); + +@ffi.Native() +external int std_VecI32_length( + VecI32 self, +); + +@ffi.Native() +external VecI32 std_VecI32_new( + int length, +); + +@ffi.Native() +external VecI32 std_VecI32_new_1( + int length, + int val, +); + +@ffi.Native)>() +external VecI32 std_VecI32_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecI32_push_back( + VecI32 self, + int val, +); + +@ffi.Native() +external void std_VecI32_reserve( + VecI32 self, + int new_len, +); + +@ffi.Native() +external void std_VecI32_resize( + VecI32 self, + int new_len, +); + +@ffi.Native() +external void std_VecI32_set( + VecI32 self, + int index, + int val, +); + +@ffi.Native() +external void std_VecI32_shrink_to_fit( + VecI32 self, +); + +@ffi.Native() +external void std_VecI64_clear( + VecI64 self, +); + +@ffi.Native() +external VecI64 std_VecI64_clone( + VecI64 self, +); + +@ffi.Native Function(VecI64)>() +external ffi.Pointer std_VecI64_data( + VecI64 self, +); + +@ffi.Native() +external void std_VecI64_extend( + VecI64 self, + VecI64 other, +); + +@ffi.Native() +external void std_VecI64_free( + VecI64 self, +); + +@ffi.Native() +external int std_VecI64_get( + VecI64 self, + int index, +); + +@ffi.Native() +external int std_VecI64_length( + VecI64 self, +); + +@ffi.Native() +external VecI64 std_VecI64_new( + int length, +); + +@ffi.Native() +external VecI64 std_VecI64_new_1( + int length, + int val, +); + +@ffi.Native)>() +external VecI64 std_VecI64_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecI64_push_back( + VecI64 self, + int val, +); + +@ffi.Native() +external void std_VecI64_reserve( + VecI64 self, + int new_len, +); + +@ffi.Native() +external void std_VecI64_resize( + VecI64 self, + int new_len, +); + +@ffi.Native() +external void std_VecI64_set( + VecI64 self, + int index, + int val, +); + +@ffi.Native() +external void std_VecI64_shrink_to_fit( + VecI64 self, +); + +@ffi.Native() +external void std_VecI8_clear( + VecI8 self, +); + +@ffi.Native() +external VecI8 std_VecI8_clone( + VecI8 self, +); + +@ffi.Native Function(VecI8)>() +external ffi.Pointer std_VecI8_data( + VecI8 self, +); + +@ffi.Native() +external void std_VecI8_extend( + VecI8 self, + VecI8 other, +); + +@ffi.Native() +external void std_VecI8_free( + VecI8 self, +); + +@ffi.Native() +external int std_VecI8_get( + VecI8 self, + int index, +); + +@ffi.Native() +external int std_VecI8_length( + VecI8 self, +); + +@ffi.Native() +external VecI8 std_VecI8_new( + int length, +); + +@ffi.Native() +external VecI8 std_VecI8_new_1( + int length, + int val, +); + +@ffi.Native)>() +external VecI8 std_VecI8_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecI8_push_back( + VecI8 self, + int val, +); + +@ffi.Native() +external void std_VecI8_reserve( + VecI8 self, + int new_len, +); + +@ffi.Native() +external void std_VecI8_resize( + VecI8 self, + int new_len, +); + +@ffi.Native() +external void std_VecI8_set( + VecI8 self, + int index, + int val, +); + +@ffi.Native() +external void std_VecI8_shrink_to_fit( + VecI8 self, +); + +@ffi.Native() +external void std_VecU16_clear( + VecU16 self, +); + +@ffi.Native() +external VecU16 std_VecU16_clone( + VecU16 self, +); + +@ffi.Native Function(VecU16)>() +external ffi.Pointer std_VecU16_data( + VecU16 self, +); + +@ffi.Native() +external void std_VecU16_extend( + VecU16 self, + VecU16 other, +); + +@ffi.Native() +external void std_VecU16_free( + VecU16 self, +); + +@ffi.Native() +external int std_VecU16_get( + VecU16 self, + int index, +); + +@ffi.Native() +external int std_VecU16_length( + VecU16 self, +); + +@ffi.Native() +external VecU16 std_VecU16_new( + int length, +); + +@ffi.Native() +external VecU16 std_VecU16_new_1( + int length, + int val, +); + +@ffi.Native)>() +external VecU16 std_VecU16_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecU16_push_back( + VecU16 self, + int val, +); + +@ffi.Native() +external void std_VecU16_reserve( + VecU16 self, + int new_len, +); + +@ffi.Native() +external void std_VecU16_resize( + VecU16 self, + int new_len, +); + +@ffi.Native() +external void std_VecU16_set( + VecU16 self, + int index, + int val, +); + +@ffi.Native() +external void std_VecU16_shrink_to_fit( + VecU16 self, +); + +@ffi.Native() +external void std_VecU32_clear( + VecU32 self, +); + +@ffi.Native() +external VecU32 std_VecU32_clone( + VecU32 self, +); + +@ffi.Native Function(VecU32)>() +external ffi.Pointer std_VecU32_data( + VecU32 self, +); + +@ffi.Native() +external void std_VecU32_extend( + VecU32 self, + VecU32 other, +); + +@ffi.Native() +external void std_VecU32_free( + VecU32 self, +); + +@ffi.Native() +external int std_VecU32_get( + VecU32 self, + int index, +); + +@ffi.Native() +external int std_VecU32_length( + VecU32 self, +); + +@ffi.Native() +external VecU32 std_VecU32_new( + int length, +); + +@ffi.Native() +external VecU32 std_VecU32_new_1( + int length, + int val, +); + +@ffi.Native)>() +external VecU32 std_VecU32_new_2( + int length, + ffi.Pointer val_ptr, +); + +@ffi.Native() +external void std_VecU32_push_back( + VecU32 self, + int val, +); + +@ffi.Native() +external void std_VecU32_reserve( + VecU32 self, + int new_len, +); + +@ffi.Native() +external void std_VecU32_resize( + VecU32 self, + int new_len, +); + +@ffi.Native() +external void std_VecU32_set( + VecU32 self, + int index, + int val, +); + +@ffi.Native() +external void std_VecU32_shrink_to_fit( + VecU32 self, +); + +@ffi.Native() +external void std_VecU64_clear( + VecU64 self, +); + +@ffi.Native() +external VecU64 std_VecU64_clone( + VecU64 self, +); + +@ffi.Native Function(VecU64)>() +external ffi.Pointer std_VecU64_data( + VecU64 self, +); + +@ffi.Native() +external void std_VecU64_extend( + VecU64 self, + VecU64 other, +); + +@ffi.Native() +external void std_VecU64_free( + VecU64 self, +); + +@ffi.Native() +external int std_VecU64_get( + VecU64 self, + int index, +); + +@ffi.Native() +external int std_VecU64_length( + VecU64 self, +); + +@ffi.Native() +external VecU64 std_VecU64_new( + int length, +); + +@ffi.Native() +external VecU64 std_VecU64_new_1( + int length, + int val, ); -ffi.Pointer stbir_resize_uint8_linear( - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - StbirPixelLayout pixel_type, -) => - _stbir_resize_uint8_linear( - input_pixels, - input_w, - input_h, - input_stride_in_bytes, - output_pixels, - output_w, - output_h, - output_stride_in_bytes, - pixel_type.value, - ); +@ffi.Native)>() +external VecU64 std_VecU64_new_2( + int length, + ffi.Pointer val_ptr, +); -/// =============================================================== -/// Simple-complexity API -/// -/// If output_pixels is NULL (0), then we will allocate the buffer and return it to you. -/// -------------------------------- -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.Pointer, - ffi.Int, - ffi.Int, - ffi.Int, - ffi.UnsignedInt)>(symbol: 'stbir_resize_uint8_srgb') -external ffi.Pointer _stbir_resize_uint8_srgb( - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - int pixel_type, +@ffi.Native() +external void std_VecU64_push_back( + VecU64 self, + int val, ); -ffi.Pointer stbir_resize_uint8_srgb( - ffi.Pointer input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - StbirPixelLayout pixel_type, -) => - _stbir_resize_uint8_srgb( - input_pixels, - input_w, - input_h, - input_stride_in_bytes, - output_pixels, - output_w, - output_h, - output_stride_in_bytes, - pixel_type.value, - ); +@ffi.Native() +external void std_VecU64_reserve( + VecU64 self, + int new_len, +); -@ffi.Native< - ffi.Void Function(ffi.Pointer, ffi.Pointer, ffi.Int, - ffi.Pointer, ffi.Int)>() -external void stbir_set_buffer_ptrs( - ffi.Pointer resize, - ffi.Pointer input_pixels, - int input_stride_in_bytes, - ffi.Pointer output_pixels, - int output_stride_in_bytes, +@ffi.Native() +external void std_VecU64_resize( + VecU64 self, + int new_len, ); -/// =============================================================== -/// You can update these parameters any time after resize_init and there is no cost -/// -------------------------------- -@ffi.Native< - ffi.Void Function(ffi.Pointer, ffi.UnsignedInt, - ffi.UnsignedInt)>(symbol: 'stbir_set_datatypes') -external void _stbir_set_datatypes( - ffi.Pointer resize, - int input_type, - int output_type, +@ffi.Native() +external void std_VecU64_set( + VecU64 self, + int index, + int val, ); -void stbir_set_datatypes( - ffi.Pointer resize, - StbirDataType input_type, - StbirDataType output_type, -) => - _stbir_set_datatypes( - resize, - input_type.value, - output_type.value, - ); +@ffi.Native() +external void std_VecU64_shrink_to_fit( + VecU64 self, +); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.UnsignedInt, - ffi.UnsignedInt)>(symbol: 'stbir_set_edgemodes') -external int _stbir_set_edgemodes( - ffi.Pointer resize, - int horizontal_edge, - int vertical_edge, +@ffi.Native() +external void std_VecU8_clear( + VecU8 self, ); -int stbir_set_edgemodes( - ffi.Pointer resize, - StbirEdge horizontal_edge, - StbirEdge vertical_edge, -) => - _stbir_set_edgemodes( - resize, - horizontal_edge.value, - vertical_edge.value, - ); +@ffi.Native() +external VecU8 std_VecU8_clone( + VecU8 self, +); -@ffi.Native< - ffi.Int Function( - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer)>() -external int stbir_set_filter_callbacks( - ffi.Pointer resize, - ffi.Pointer horizontal_filter, - ffi.Pointer horizontal_support, - ffi.Pointer vertical_filter, - ffi.Pointer vertical_support, +@ffi.Native Function(VecU8)>() +external ffi.Pointer std_VecU8_data( + VecU8 self, ); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.UnsignedInt, - ffi.UnsignedInt)>(symbol: 'stbir_set_filters') -external int _stbir_set_filters( - ffi.Pointer resize, - int horizontal_filter, - int vertical_filter, +@ffi.Native() +external void std_VecU8_extend( + VecU8 self, + VecU8 other, ); -int stbir_set_filters( - ffi.Pointer resize, - StbirFilter horizontal_filter, - StbirFilter vertical_filter, -) => - _stbir_set_filters( - resize, - horizontal_filter.value, - vertical_filter.value, - ); +@ffi.Native() +external void std_VecU8_free( + VecU8 self, +); -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.Double, ffi.Double, - ffi.Double, ffi.Double)>() -external int stbir_set_input_subrect( - ffi.Pointer resize, - double s0, - double t0, - double s1, - double t1, +@ffi.Native() +external int std_VecU8_get( + VecU8 self, + int index, ); -/// when inputting AND outputting non-premultiplied alpha pixels, we use a slower but higher quality technique -/// that fills the zero alpha pixel's RGB values with something plausible. If you don't care about areas of -/// zero alpha, you can call this function to get about a 25% speed improvement for STBIR_RGBA to STBIR_RGBA -/// types of resizes. -@ffi.Native, ffi.Int)>() -external int stbir_set_non_pm_alpha_speed_over_quality( - ffi.Pointer resize, - int non_pma_alpha_speed_over_quality, +@ffi.Native() +external int std_VecU8_length( + VecU8 self, ); -@ffi.Native< - ffi.Int Function( - ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, ffi.Int)>() -external int stbir_set_output_pixel_subrect( - ffi.Pointer resize, - int subx, - int suby, - int subw, - int subh, +@ffi.Native() +external VecU8 std_VecU8_new( + int length, ); -@ffi.Native< - ffi.Void Function( - ffi.Pointer, - ffi.Pointer, - ffi.Pointer)>() -external void stbir_set_pixel_callbacks( - ffi.Pointer resize, - ffi.Pointer input_cb, - ffi.Pointer output_cb, +@ffi.Native() +external VecU8 std_VecU8_new_1( + int length, + int val, ); -/// =============================================================== -/// If you call any of these functions, you will trigger a sampler rebuild! -/// -------------------------------- -@ffi.Native< - ffi.Int Function(ffi.Pointer, ffi.UnsignedInt, - ffi.UnsignedInt)>(symbol: 'stbir_set_pixel_layouts') -external int _stbir_set_pixel_layouts( - ffi.Pointer resize, - int input_pixel_layout, - int output_pixel_layout, +@ffi.Native)>() +external VecU8 std_VecU8_new_2( + int length, + ffi.Pointer val_ptr, ); -int stbir_set_pixel_layouts( - ffi.Pointer resize, - StbirPixelLayout input_pixel_layout, - StbirPixelLayout output_pixel_layout, -) => - _stbir_set_pixel_layouts( - resize, - input_pixel_layout.value, - output_pixel_layout.value, - ); +@ffi.Native() +external void std_VecU8_push_back( + VecU8 self, + int val, +); -@ffi.Native< - ffi.Int Function( - ffi.Pointer, ffi.Int, ffi.Int, ffi.Int, ffi.Int)>() -external int stbir_set_pixel_subrect( - ffi.Pointer resize, - int subx, - int suby, - int subw, - int subh, +@ffi.Native() +external void std_VecU8_reserve( + VecU8 self, + int new_len, ); -@ffi.Native< - ffi.Void Function(ffi.Pointer, ffi.Pointer)>() -external void stbir_set_user_data( - ffi.Pointer resize, - ffi.Pointer user_data, +@ffi.Native() +external void std_VecU8_resize( + VecU8 self, + int new_len, +); + +@ffi.Native() +external void std_VecU8_set( + VecU8 self, + int index, + int val, +); + +@ffi.Native() +external void std_VecU8_shrink_to_fit( + VecU8 self, ); const addresses = _SymbolAddresses(); @@ -2629,6 +5358,22 @@ class _SymbolAddresses { ffi.Pointer> get mnn_cv_matrix_destroy => ffi.Native.addressOf(self.mnn_cv_matrix_destroy); + ffi.Pointer> + get mnn_expr_Expr_free => ffi.Native.addressOf(self.mnn_expr_Expr_free); + ffi.Pointer)>> + get mnn_expr_VARMAP_free => + ffi.Native.addressOf(self.mnn_expr_VARMAP_free); + ffi.Pointer)>> + get mnn_expr_VARP_free => ffi.Native.addressOf(self.mnn_expr_VARP_free); + ffi.Pointer)>> + get mnn_expr_Variable_Info_free => + ffi.Native.addressOf(self.mnn_expr_Variable_Info_free); + ffi.Pointer)>> + get mnn_expr_VecVARP_free => + ffi.Native.addressOf(self.mnn_expr_VecVARP_free); + ffi.Pointer)>> + get mnn_expr_VecWeakEXPRP_free => + ffi.Native.addressOf(self.mnn_expr_VecWeakEXPRP_free); ffi.Pointer> get mnn_interpreter_destroy => ffi.Native.addressOf(self.mnn_interpreter_destroy); @@ -2643,6 +5388,28 @@ class _SymbolAddresses { get stbi_image_free => ffi.Native.addressOf(self.stbi_image_free); ffi.Pointer)>> get stbir_free_samplers => ffi.Native.addressOf(self.stbir_free_samplers); + ffi.Pointer> + get std_VecF16_free => ffi.Native.addressOf(self.std_VecF16_free); + ffi.Pointer> + get std_VecF32_free => ffi.Native.addressOf(self.std_VecF32_free); + ffi.Pointer> + get std_VecF64_free => ffi.Native.addressOf(self.std_VecF64_free); + ffi.Pointer> + get std_VecI16_free => ffi.Native.addressOf(self.std_VecI16_free); + ffi.Pointer> + get std_VecI32_free => ffi.Native.addressOf(self.std_VecI32_free); + ffi.Pointer> + get std_VecI64_free => ffi.Native.addressOf(self.std_VecI64_free); + ffi.Pointer> + get std_VecI8_free => ffi.Native.addressOf(self.std_VecI8_free); + ffi.Pointer> + get std_VecU16_free => ffi.Native.addressOf(self.std_VecU16_free); + ffi.Pointer> + get std_VecU32_free => ffi.Native.addressOf(self.std_VecU32_free); + ffi.Pointer> + get std_VecU64_free => ffi.Native.addressOf(self.std_VecU64_free); + ffi.Pointer> + get std_VecU8_free => ffi.Native.addressOf(self.std_VecU8_free); } enum DimensionType { @@ -2661,6 +5428,8 @@ enum DimensionType { }; } +typedef EXPRP_t = ffi.Pointer; + /// Error code enum enum ErrorCode { NO_ERROR(0), @@ -2811,6 +5580,10 @@ enum MapType { }; } +typedef Net_t = ffi.Pointer; +typedef OpT_t = ffi.Pointer; +typedef Op_t = ffi.Pointer; + final class STBIR_RESIZE extends ffi.Struct { external ffi.Pointer user_data; @@ -3153,6 +5926,32 @@ final class UnnamedUnion2 extends ffi.Union { external int mode; } +typedef VARMAP_PAIR_t = ffi.Pointer; +typedef VARMAP_t = ffi.Pointer; +typedef VARP_t = ffi.Pointer; + +final class Variable_expr_pair extends ffi.Struct { + external EXPRP_t expr; + + @ffi.Int() + external int index; +} + +typedef VecChar = ffi.Pointer; +typedef VecF16 = ffi.Pointer; +typedef VecF32 = ffi.Pointer; +typedef VecF64 = ffi.Pointer; +typedef VecI16 = ffi.Pointer; +typedef VecI32 = ffi.Pointer; +typedef VecI64 = ffi.Pointer; +typedef VecI8 = ffi.Pointer; +typedef VecU16 = ffi.Pointer; +typedef VecU32 = ffi.Pointer; +typedef VecU64 = ffi.Pointer; +typedef VecU8 = ffi.Pointer; +typedef VecUChar = ffi.Pointer; +typedef VecVARP_t = ffi.Pointer; +typedef VecWeakEXPRP_t = ffi.Pointer; typedef __darwin_off_t = __int64_t; typedef __int64_t = ffi.LongLong; typedef Dart__int64_t = int; @@ -3270,6 +6069,10 @@ final class __sbuf extends ffi.Struct { external int _size; } +typedef double_t = ffi.Double; +typedef Dartdouble_t = double; +typedef float_t = ffi.Float; +typedef Dartfloat_t = double; typedef fpos_t = __darwin_off_t; /// The raw representation of an image passed around by generated @@ -3559,6 +6362,23 @@ final class mnn_cv_rect_t extends ffi.Struct { external double bottom; } +typedef mnn_expr_Expr_t = ffi.Pointer; + +final class mnn_expr_Variable_Info extends ffi.Struct { + @ffi.Int() + external int order; + + external ffi.Pointer dim; + + @ffi.Size() + external int ndim; + + external halide_type_c_t type; + + @ffi.Size() + external int size; +} + /// Forward type enum */ /// // typedef mnn_forward_type mnn_forward_type_t; typedef mnn_forward_type_t = ffi.Int; @@ -3693,3 +6513,5 @@ typedef stbir_uint64 = ffi.Uint64; typedef Dartstbir_uint64 = int; typedef stbir_uint8 = ffi.Uint8; typedef Dartstbir_uint8 = int; +typedef uchar = ffi.UnsignedChar; +typedef Dartuchar = int; diff --git a/lib/src/halide_runtime.dart b/lib/src/halide_runtime.dart index ae0d20b..cf5cea8 100644 --- a/lib/src/halide_runtime.dart +++ b/lib/src/halide_runtime.dart @@ -9,65 +9,114 @@ import 'package:ffi/ffi.dart'; import 'base.dart'; import 'g/mnn.g.dart' as c; -class HalideType extends NativeObject { - static final _finalizer = ffi.NativeFinalizer(calloc.nativeFree); - - HalideType.fromPointer(ffi.Pointer ptr, {super.attach, super.externalSize}) - : super(ptr.cast()); - - factory HalideType.create({ - c.HalideTypeCode code = c.HalideTypeCode.halide_type_int, - int bits = 0, - int lanes = 1, - }) { - final p = malloc() - ..ref.code = code.value - ..ref.bits = bits - ..ref.lanes = lanes; - return HalideType.fromPointer(p); +class HalideType with ComparableMixin { + final c.HalideTypeCode code; + final int bits; + final int lanes; + + const HalideType({this.code = c.HalideTypeCode.halide_type_int, this.bits = 0, this.lanes = 1}); + + factory HalideType.fromNative(c.halide_type_c_t type) => + HalideType(code: c.HalideTypeCode.fromValue(type.code), bits: type.bits, lanes: type.lanes); + + static const bf16 = HalideType(code: c.HalideTypeCode.halide_type_bfloat, bits: 16); + static const f32 = HalideType(code: c.HalideTypeCode.halide_type_float, bits: 32); + static const f64 = HalideType(code: c.HalideTypeCode.halide_type_float, bits: 64); + static const bool_ = HalideType(code: c.HalideTypeCode.halide_type_uint, bits: 1); + static const u8 = HalideType(code: c.HalideTypeCode.halide_type_uint, bits: 8); + static const u16 = HalideType(code: c.HalideTypeCode.halide_type_uint, bits: 16); + static const u32 = HalideType(code: c.HalideTypeCode.halide_type_uint, bits: 32); + static const u64 = HalideType(code: c.HalideTypeCode.halide_type_uint, bits: 64); + static const i8 = HalideType(code: c.HalideTypeCode.halide_type_int, bits: 8); + static const i16 = HalideType(code: c.HalideTypeCode.halide_type_int, bits: 16); + static const i32 = HalideType(code: c.HalideTypeCode.halide_type_int, bits: 32); + static const i64 = HalideType(code: c.HalideTypeCode.halide_type_int, bits: 64); + + static HalideType of() { + if (T == ffi.Float) { + return HalideType.f32; + } else if (T == ffi.Double) { + return HalideType.f64; + } else if (T == ffi.Bool) { + return HalideType.bool_; + } else if (T == ffi.Uint8) { + return HalideType.u8; + } else if (T == ffi.Uint16) { + return HalideType.u16; + } else if (T == ffi.Uint32) { + return HalideType.u32; + } else if (T == ffi.Uint64) { + return HalideType.u64; + } else if (T == ffi.Int8) { + return HalideType.i8; + } else if (T == ffi.Int16) { + return HalideType.i16; + } else if (T == ffi.Int32) { + return HalideType.i32; + } else if (T == ffi.Int64) { + return HalideType.i64; + } else { + throw ArgumentError.value(T, 'T', 'Unsupported type'); + } } - factory HalideType.fromNative(c.halide_type_c_t type) { - final p = calloc()..ref = type; - return HalideType.fromPointer(p); - } - - factory HalideType.bf16() => HalideType.create(code: c.HalideTypeCode.halide_type_bfloat, bits: 16); - factory HalideType.f32() => HalideType.create(code: c.HalideTypeCode.halide_type_float, bits: 32); - factory HalideType.f64() => HalideType.create(code: c.HalideTypeCode.halide_type_float, bits: 64); - factory HalideType.bool() => HalideType.create(code: c.HalideTypeCode.halide_type_uint, bits: 1); - factory HalideType.u8() => HalideType.create(code: c.HalideTypeCode.halide_type_uint, bits: 8); - factory HalideType.u16() => HalideType.create(code: c.HalideTypeCode.halide_type_uint, bits: 16); - factory HalideType.u32() => HalideType.create(code: c.HalideTypeCode.halide_type_uint, bits: 32); - factory HalideType.u64() => HalideType.create(code: c.HalideTypeCode.halide_type_uint, bits: 64); - factory HalideType.i8() => HalideType.create(code: c.HalideTypeCode.halide_type_int, bits: 8); - factory HalideType.i16() => HalideType.create(code: c.HalideTypeCode.halide_type_int, bits: 16); - factory HalideType.i32() => HalideType.create(code: c.HalideTypeCode.halide_type_int, bits: 32); - factory HalideType.i64() => HalideType.create(code: c.HalideTypeCode.halide_type_int, bits: 64); - - c.HalideTypeCode get code => c.HalideTypeCode.fromValue(ref.code); - int get bits => ref.bits; - int get lanes => ref.lanes; - /// Size in bytes for a single element, even if width is not 1, of this type. int get bytes => (bits + 7) ~/ 8; - c.halide_type_c_t get ref => ptr.cast().ref; + bool get isInt => [c.HalideTypeCode.halide_type_int, c.HalideTypeCode.halide_type_uint].contains(code); + bool get isFloat => + [c.HalideTypeCode.halide_type_float, c.HalideTypeCode.halide_type_bfloat].contains(code); + + _HalideTypeNative get native => _HalideTypeNative(this); @override - ffi.NativeFinalizer get finalizer => _finalizer; + List get props => [bits, lanes, code]; @override - void release() { - malloc.free(ptr); + String toString() { + return switch (this) { + HalideType.bf16 => 'bfloat16', + HalideType.f32 => 'float32', + HalideType.f64 => 'float64', + HalideType.bool_ => 'bool', + HalideType.u8 => 'uint8', + HalideType.u16 => 'uint16', + HalideType.u32 => 'uint32', + HalideType.u64 => 'uint64', + HalideType.i8 => 'int8', + HalideType.i16 => 'int16', + HalideType.i32 => 'int32', + HalideType.i64 => 'int64', + _ => 'HalideType(code=$code, bits=$bits, lanes=$lanes)' + }; + } +} + +class _HalideTypeNative extends NativeObject { + static final _finalizer = ffi.NativeFinalizer(calloc.nativeFree); + _HalideTypeNative.fromPointer(ffi.Pointer ptr, {super.attach, super.externalSize}) + : super(ptr.cast()); + + factory _HalideTypeNative(HalideType type) { + final ptr = calloc() + ..ref.code = type.code.value + ..ref.bits = type.bits + ..ref.lanes = type.lanes; + return _HalideTypeNative.fromPointer(ptr, attach: true, externalSize: ffi.sizeOf()); } @override - List get props => [bits, lanes, code]; + ffi.NativeFinalizer get finalizer => _finalizer; + + c.halide_type_c_t get ref => ptr.cast().ref; @override - String toString() { - return 'HalideType(code=$code, bits=$bits, lanes=$lanes)'; + List get props => [ref.code, ref.bits, ref.lanes]; + + @override + void release() { + finalizer.detach(this); + calloc.free(ptr); } } diff --git a/lib/src/image_process.dart b/lib/src/image_process.dart index cd72588..1545978 100644 --- a/lib/src/image_process.dart +++ b/lib/src/image_process.dart @@ -168,7 +168,8 @@ class ImageProcess extends NativeObject { Image? image, }) { final pImage = image == null ? ffi.nullptr : image.ptr; - final ptr = c.mnn_cv_image_process_create_image_tensor(type.ref, width, height, bytesPerChannel, pImage); + final ptr = + c.mnn_cv_image_process_create_image_tensor(type.native.ref, width, height, bytesPerChannel, pImage); return Tensor.fromPointer(ptr); } diff --git a/lib/src/tensor.dart b/lib/src/tensor.dart index 3d8807d..18af3c6 100644 --- a/lib/src/tensor.dart +++ b/lib/src/tensor.dart @@ -30,7 +30,7 @@ class Tensor extends NativeObject { }) { final pShape = calloc(shape.length); pShape.cast().asTypedList(shape.length).setAll(0, shape); - final p = c.mnn_tensor_create_device(pShape, shape.length, type.ref, dimType); + final p = c.mnn_tensor_create_device(pShape, shape.length, type.native.ref, dimType); return Tensor.fromPointer(p); } @@ -55,7 +55,7 @@ class Tensor extends NativeObject { if (data != null) { pData.asTypedList(data.length).setAll(0, data); } - final p = c.mnn_tensor_create_with_data(pShape, shape.length, type.ref, pData.cast(), dimType); + final p = c.mnn_tensor_create_with_data(pShape, shape.length, type.native.ref, pData.cast(), dimType); return Tensor.fromPointer(p); } @@ -224,7 +224,16 @@ class Tensor extends NativeObject { /// @brief Get data type /// /// @return Data type - HalideType get type => HalideType.fromPointer(c.mnn_tensor_get_type(ptr)); + HalideType get type { + final p = c.mnn_tensor_get_type(ptr); + final rval = HalideType( + code: c.HalideTypeCode.fromValue(p.ref.code), + bits: p.ref.bits, + lanes: p.ref.lanes, + ); + calloc.free(p); + return rval; + } /// @brief Map tensor for access /// @@ -343,26 +352,26 @@ extension DataTypeExt on DataType { switch (this) { case DataType.DataType_DT_DOUBLE: case DataType.DataType_DT_FLOAT: - return HalideType.f32(); + return HalideType.f32; case DataType.DataType_DT_BFLOAT16: - return HalideType.bf16(); + return HalideType.bf16; case DataType.DataType_DT_QINT32: case DataType.DataType_DT_INT32: case DataType.DataType_DT_BOOL: case DataType.DataType_DT_INT64: - return HalideType.i32(); + return HalideType.i32; case DataType.DataType_DT_QINT8: case DataType.DataType_DT_INT8: - return HalideType.i8(); + return HalideType.i8; case DataType.DataType_DT_QUINT8: case DataType.DataType_DT_UINT8: - return HalideType.u8(); + return HalideType.u8; case DataType.DataType_DT_QUINT16: case DataType.DataType_DT_UINT16: - return HalideType.u16(); + return HalideType.u16; case DataType.DataType_DT_QINT16: case DataType.DataType_DT_INT16: - return HalideType.i16(); + return HalideType.i16; default: throw MNNException('Unsupported data type: $this'); } diff --git a/lib/src/vec.dart b/lib/src/vec.dart new file mode 100644 index 0000000..c7f62e8 --- /dev/null +++ b/lib/src/vec.dart @@ -0,0 +1,790 @@ +// Copyright (c) 2024, rainyl and all contributors. All rights reserved. +// Use of this source code is governed by a Apache-2.0 license +// that can be found in the LICENSE file. + +import 'dart:collection'; +import 'dart:convert'; +import 'dart:ffi' as ffi; +import 'dart:typed_data'; + +import 'package:ffi/ffi.dart'; + +import 'g/mnn.g.dart' as C; + +abstract class Vec with IterableMixin implements ffi.Finalizable { + Vec.fromPointer(this.ptr); + + N ptr; + + @override + int get length; + + T operator [](int idx); + void operator []=(int idx, T value); + + void dispose(); + Vec clone(); + int size(); + void add(T element); + void resize(int newSize); + void reserve(int newCapacity); + void clear(); + void shrinkToFit(); + void extend(Vec other); + + ffi.Pointer asVoid(); + + @override + bool operator ==(Object other) { + if (other is! Vec) return false; + if (identical(this, other)) return true; + if (length != other.length) return false; + return hashCode == other.hashCode; + } + + @override + int get hashCode => ptr.hashCode; +} + +abstract class VecIterator implements Iterator { + int currentIndex = -1; + int get length; + T operator [](int idx); + + @override + T get current { + if (currentIndex >= 0 && currentIndex < length) { + return this[currentIndex]; + } + throw IndexError.withLength(currentIndex, length); + } + + @override + bool moveNext() { + if (currentIndex < length - 1) { + currentIndex++; + return true; + } + return false; + } +} + +abstract class VecUnmodifible extends Vec { + VecUnmodifible.fromPointer(super.ptr) : super.fromPointer(); + + @override + void operator []=(int idx, T value) => throw UnsupportedError("Unmodifiable Vec"); + + @override + void add(T element) => throw UnsupportedError("Unmodifiable Vec"); + @override + void resize(int newSize) => throw UnsupportedError("Unmodifiable Vec"); + @override + void reserve(int newCapacity) => throw UnsupportedError("Unmodifiable Vec"); + @override + void clear() => throw UnsupportedError("Unmodifiable Vec"); + @override + void shrinkToFit() => throw UnsupportedError("Unmodifiable Vec"); + @override + void extend(Vec other) => throw UnsupportedError("Unmodifiable Vec"); +} + +class VecU8 extends Vec { + VecU8.fromPointer(super.ptr, {bool attach = true, int? length}) : super.fromPointer() { + if (attach) { + finalizer.attach( + this, + ptr.cast(), + detach: this, + externalSize: length == null ? null : length * ffi.sizeOf(), + ); + } + } + + factory VecU8([int length = 0, int value = 0]) => + VecU8.fromPointer(C.std_VecU8_new_1(length, value), length: length); + + factory VecU8.fromList(List pts) { + final length = pts.length; + final p = C.std_VecU8_new(length); + final pdata = C.std_VecU8_data(p); + pdata.cast().asTypedList(length).setAll(0, pts); + return VecU8.fromPointer(p, length: pts.length); + } + + factory VecU8.generate(int length, int Function(int i) generator) { + final p = C.std_VecU8_new(length); + for (var i = 0; i < length; i++) { + C.std_VecU8_set(p, i, generator(i)); + } + return VecU8.fromPointer(p, length: length); + } + + static final finalizer = ffi.NativeFinalizer(C.addresses.std_VecU8_free); + + @override + int get length => C.std_VecU8_length(ptr); + + ffi.Pointer get dataPtr => C.std_VecU8_data(ptr); + + /// Returns a view of native pointer + Uint8List get data => dataPtr.cast().asTypedList(length); + Uint8List get dataView => dataPtr.cast().asTypedList(length); + + /// ~~alias of data~~ + /// + /// This method will return a full copy of [data] + /// + /// https://github.com/rainyl/opencv_dart/issues/85 + Uint8List toU8List() => Uint8List.fromList(data); + + @override + VecU8 clone() => VecU8.fromPointer(C.std_VecU8_clone(ptr)); + + @override + Iterator get iterator => VecU8Iterator(dataView); + + @override + void dispose() { + finalizer.detach(this); + C.std_VecU8_free(ptr); + } + + @override + ffi.Pointer asVoid() => dataPtr.cast(); + + @override + void operator []=(int idx, int value) => C.std_VecU8_set(ptr, idx, value); + + @override + int operator [](int idx) => C.std_VecU8_get(ptr, idx); + + @override + void add(int element) => C.std_VecU8_push_back(ptr, element); + + @override + void clear() => C.std_VecU8_clear(ptr); + + @override + void extend(Vec other) => C.std_VecU8_extend(ptr, (other as VecU8).ptr); + + @override + void reserve(int newCapacity) => C.std_VecU8_reserve(ptr, newCapacity); + + @override + void resize(int newSize) => C.std_VecU8_resize(ptr, newSize); + + @override + void shrinkToFit() => C.std_VecU8_shrink_to_fit(ptr); + + @override + int size() => C.std_VecU8_length(ptr); +} + +class VecU8Iterator extends VecIterator { + VecU8Iterator(this.dataView); + Uint8List dataView; + + @override + int get length => dataView.length; + + @override + int operator [](int idx) => dataView[idx]; +} + +class VecI8 extends Vec { + VecI8.fromPointer(super.ptr, {bool attach = true, int? length}) : super.fromPointer() { + if (attach) { + finalizer.attach( + this, + ptr.cast(), + detach: this, + externalSize: length == null ? null : length * ffi.sizeOf(), + ); + } + } + + factory VecI8([int length = 0, int value = 0]) => + VecI8.fromPointer(C.std_VecI8_new_1(length, value), length: length); + factory VecI8.fromList(List pts) { + final length = pts.length; + final p = C.std_VecI8_new(length); + final pdata = C.std_VecI8_data(p); + pdata.cast().asTypedList(length).setAll(0, pts); + return VecI8.fromPointer(p, length: pts.length); + } + + factory VecI8.generate(int length, int Function(int i) generator) { + final p = C.std_VecI8_new(length); + for (var i = 0; i < length; i++) { + C.std_VecI8_set(p, i, generator(i)); + } + return VecI8.fromPointer(p, length: length); + } + + static final finalizer = ffi.NativeFinalizer(C.addresses.std_VecI8_free); + + @override + int get length => C.std_VecI8_length(ptr); + + ffi.Pointer get dataPtr => C.std_VecI8_data(ptr); + + Uint8List get data => dataPtr.cast().asTypedList(length); + Int8List get dataView => dataPtr.cast().asTypedList(length); + + String asString() => utf8.decode(data); + + @override + VecI8 clone() => VecI8.fromPointer(C.std_VecI8_clone(ptr)); + + @override + Iterator get iterator => VecI8Iterator(dataView); + + @override + void dispose() { + finalizer.detach(this); + C.std_VecI8_free(ptr); + } + + @override + ffi.Pointer asVoid() => dataPtr.cast(); + + @override + void operator []=(int idx, int value) => C.std_VecI8_set(ptr, idx, value); + + @override + int operator [](int idx) => C.std_VecI8_get(ptr, idx); + + @override + void add(int element) => C.std_VecI8_push_back(ptr, element); + + @override + void clear() => C.std_VecI8_clear(ptr); + + @override + void extend(Vec other) => C.std_VecI8_extend(ptr, (other as VecI8).ptr); + + @override + void reserve(int newCapacity) => C.std_VecI8_reserve(ptr, newCapacity); + + @override + void resize(int newSize) => C.std_VecI8_resize(ptr, newSize); + + @override + void shrinkToFit() => C.std_VecI8_shrink_to_fit(ptr); + + @override + int size() => C.std_VecI8_length(ptr); +} + +class VecI8Iterator extends VecIterator { + VecI8Iterator(this.dataView); + Int8List dataView; + + @override + int get length => dataView.length; + + @override + int operator [](int idx) => dataView[idx]; +} + +class VecU16 extends Vec { + VecU16.fromPointer(super.ptr, {bool attach = true, int? length}) : super.fromPointer() { + if (attach) { + finalizer.attach( + this, + ptr.cast(), + detach: this, + externalSize: length == null ? null : length * ffi.sizeOf(), + ); + } + } + + factory VecU16([int length = 0, int value = 0]) => + VecU16.fromPointer(C.std_VecU16_new_1(length, value), length: length); + + factory VecU16.fromList(List pts) { + final length = pts.length; + final p = C.std_VecU16_new(length); + final pdata = C.std_VecU16_data(p); + pdata.asTypedList(length).setAll(0, pts); + return VecU16.fromPointer(p, length: pts.length); + } + + factory VecU16.generate(int length, int Function(int i) generator) { + final p = C.std_VecU16_new(length); + for (var i = 0; i < length; i++) { + C.std_VecU16_set(p, i, generator(i)); + } + return VecU16.fromPointer(p, length: length); + } + + static final finalizer = ffi.NativeFinalizer(C.addresses.std_VecU16_free); + + @override + VecU16 clone() => VecU16.fromPointer(C.std_VecU16_clone(ptr)); + + @override + int get length => C.std_VecU16_length(ptr); + + ffi.Pointer get dataPtr => C.std_VecU16_data(ptr); + + Uint16List get data => dataPtr.cast().asTypedList(length); + + @override + Iterator get iterator => VecU16Iterator(data); + + @override + void dispose() { + finalizer.detach(this); + C.std_VecU16_free(ptr); + } + + @override + ffi.Pointer asVoid() => dataPtr.cast(); + + @override + void operator []=(int idx, int value) => data[idx] = value; + + @override + int operator [](int idx) => data[idx]; + + @override + void add(int element) => C.std_VecU16_push_back(ptr, element); + + @override + void clear() => C.std_VecU16_clear(ptr); + + @override + void extend(Vec other) => C.std_VecU16_extend(ptr, (other as VecU16).ptr); + + @override + void reserve(int newCapacity) => C.std_VecU16_reserve(ptr, newCapacity); + + @override + void resize(int newSize) => C.std_VecU16_resize(ptr, newSize); + + @override + void shrinkToFit() => C.std_VecU16_shrink_to_fit(ptr); + + @override + int size() => C.std_VecU16_length(ptr); +} + +class VecU16Iterator extends VecIterator { + VecU16Iterator(this.data); + Uint16List data; + + @override + int get length => data.length; + + @override + int operator [](int idx) => data[idx]; +} + +class VecI16 extends Vec { + VecI16.fromPointer(super.ptr, {bool attach = true, int? length}) : super.fromPointer() { + if (attach) { + finalizer.attach( + this, + ptr.cast(), + detach: this, + externalSize: length == null ? null : length * ffi.sizeOf(), + ); + } + } + + factory VecI16([int length = 0, int value = 0]) => + VecI16.fromPointer(C.std_VecI16_new_1(length, value), length: length); + + factory VecI16.fromList(List pts) { + final length = pts.length; + final p = C.std_VecI16_new(length); + final pdata = C.std_VecI16_data(p); + pdata.asTypedList(length).setAll(0, pts); + return VecI16.fromPointer(p, length: pts.length); + } + + factory VecI16.generate(int length, int Function(int i) generator) { + final p = C.std_VecI16_new(length); + for (var i = 0; i < length; i++) { + C.std_VecI16_set(p, i, generator(i)); + } + return VecI16.fromPointer(p, length: length); + } + + static final finalizer = ffi.NativeFinalizer(C.addresses.std_VecI16_free); + + @override + VecI16 clone() => VecI16.fromPointer(C.std_VecI16_clone(ptr)); + + @override + int get length => C.std_VecI16_length(ptr); + + ffi.Pointer get dataPtr => C.std_VecI16_data(ptr); + + Int16List get data => dataPtr.cast().asTypedList(length); + @override + Iterator get iterator => VecI16Iterator(data); + + @override + void dispose() { + finalizer.detach(this); + C.std_VecI16_free(ptr); + } + + @override + ffi.Pointer asVoid() => dataPtr.cast(); + + @override + void operator []=(int idx, int value) => data[idx] = value; + + @override + int operator [](int idx) => data[idx]; + + @override + void add(int element) => C.std_VecI16_push_back(ptr, element); + + @override + void clear() => C.std_VecI16_clear(ptr); + + @override + void extend(Vec other) => C.std_VecI16_extend(ptr, (other as VecI16).ptr); + + @override + void reserve(int newCapacity) => C.std_VecI16_reserve(ptr, newCapacity); + + @override + void resize(int newSize) => C.std_VecI16_resize(ptr, newSize); + + @override + void shrinkToFit() => C.std_VecI16_shrink_to_fit(ptr); + + @override + int size() => C.std_VecI16_length(ptr); +} + +class VecI16Iterator extends VecIterator { + VecI16Iterator(this.data); + Int16List data; + + @override + int get length => data.length; + + @override + int operator [](int idx) => data[idx]; +} + +class VecI32 extends Vec { + VecI32.fromPointer(super.ptr, {bool attach = true, int? length}) : super.fromPointer() { + if (attach) { + finalizer.attach( + this, + ptr.cast(), + detach: this, + externalSize: length == null ? null : length * ffi.sizeOf(), + ); + } + } + + factory VecI32([int length = 0, int value = 0]) => + VecI32.fromPointer(C.std_VecI32_new_1(length, value), length: length); + + factory VecI32.fromList(List pts) { + final length = pts.length; + final p = C.std_VecI32_new(length); + final pdata = C.std_VecI32_data(p); + pdata.asTypedList(length).setAll(0, pts); + return VecI32.fromPointer(p, length: pts.length); + } + + factory VecI32.generate(int length, int Function(int i) generator) { + final p = C.std_VecI32_new(length); + for (var i = 0; i < length; i++) { + C.std_VecI32_set(p, i, generator(i)); + } + return VecI32.fromPointer(p, length: length); + } + + static final finalizer = ffi.NativeFinalizer(C.addresses.std_VecI32_free); + + @override + VecI32 clone() => VecI32.fromPointer(C.std_VecI32_clone(ptr)); + + @override + int get length => C.std_VecI32_length(ptr); + + ffi.Pointer get dataPtr => C.std_VecI32_data(ptr); + + Int32List get data => dataPtr.cast().asTypedList(length); + + @override + Iterator get iterator => VecI32Iterator(data); + + @override + void dispose() { + finalizer.detach(this); + C.std_VecI32_free(ptr); + } + + @override + ffi.Pointer asVoid() => dataPtr.cast(); + + @override + void operator []=(int idx, int value) => C.std_VecI32_set(ptr, idx, value); + + @override + int operator [](int idx) => C.std_VecI32_get(ptr, idx); + + @override + void add(int element) => C.std_VecI32_push_back(ptr, element); + + @override + void clear() => C.std_VecI32_clear(ptr); + + @override + void extend(Vec other) => C.std_VecI32_extend(ptr, (other as VecI32).ptr); + + @override + void reserve(int newCapacity) => C.std_VecI32_reserve(ptr, newCapacity); + + @override + void resize(int newSize) => C.std_VecI32_resize(ptr, newSize); + + @override + void shrinkToFit() => C.std_VecI32_shrink_to_fit(ptr); + + @override + int size() => C.std_VecI32_length(ptr); +} + +class VecI32Iterator extends VecIterator { + VecI32Iterator(this.data); + Int32List data; + + @override + int get length => data.length; + + @override + int operator [](int idx) => data[idx]; +} + +class VecF32 extends Vec { + VecF32.fromPointer(super.ptr, {bool attach = true, int? length}) : super.fromPointer() { + if (attach) { + finalizer.attach( + this, + ptr.cast(), + detach: this, + externalSize: length == null ? null : length * ffi.sizeOf(), + ); + } + } + + factory VecF32([int length = 0, double value = 0.0]) => + VecF32.fromPointer(C.std_VecF32_new_1(length, value), length: length); + factory VecF32.fromList(List pts) { + final length = pts.length; + final p = C.std_VecF32_new(length); + final pdata = C.std_VecF32_data(p); + pdata.asTypedList(length).setAll(0, pts); + return VecF32.fromPointer(p, length: pts.length); + } + + factory VecF32.generate(int length, double Function(int i) generator) { + final p = C.std_VecF32_new(length); + for (var i = 0; i < length; i++) { + C.std_VecF32_set(p, i, generator(i)); + } + return VecF32.fromPointer(p, length: length); + } + + static final finalizer = ffi.NativeFinalizer(C.addresses.std_VecF32_free); + + @override + VecF32 clone() => VecF32.fromPointer(C.std_VecF32_clone(ptr)); + + @override + int get length => C.std_VecF32_length(ptr); + + ffi.Pointer get dataPtr => C.std_VecF32_data(ptr); + + Float32List get data => dataPtr.cast().asTypedList(length); + @override + Iterator get iterator => VecF32Iterator(data); + + @override + void dispose() { + finalizer.detach(this); + C.std_VecF32_free(ptr); + } + + @override + ffi.Pointer asVoid() => dataPtr.cast(); + + @override + void operator []=(int idx, double value) => C.std_VecF32_set(ptr, idx, value); + + @override + double operator [](int idx) => C.std_VecF32_get(ptr, idx); + + @override + void add(double element) => C.std_VecF32_push_back(ptr, element); + + @override + void clear() => C.std_VecF32_clear(ptr); + + @override + void extend(Vec other) => C.std_VecF32_extend(ptr, (other as VecF32).ptr); + + @override + void reserve(int newCapacity) => C.std_VecF32_reserve(ptr, newCapacity); + + @override + void resize(int newSize) => C.std_VecF32_resize(ptr, newSize); + + @override + void shrinkToFit() => C.std_VecF32_shrink_to_fit(ptr); + + @override + int size() => C.std_VecF32_length(ptr); +} + +class VecF32Iterator extends VecIterator { + VecF32Iterator(this.data); + Float32List data; + + @override + int get length => data.length; + + @override + double operator [](int idx) => data[idx]; +} + +class VecF64 extends Vec { + VecF64.fromPointer(super.ptr, {bool attach = true, int? length}) : super.fromPointer() { + if (attach) { + finalizer.attach( + this, + ptr.cast(), + detach: this, + externalSize: length == null ? null : length * ffi.sizeOf(), + ); + } + } + + factory VecF64([int length = 0, double value = 0.0]) => + VecF64.fromPointer(C.std_VecF64_new_1(length, value), length: length); + factory VecF64.fromList(List pts) { + final length = pts.length; + final p = C.std_VecF64_new(length); + final pdata = C.std_VecF64_data(p); + pdata.asTypedList(length).setAll(0, pts); + return VecF64.fromPointer(p, length: pts.length); + } + + factory VecF64.generate(int length, double Function(int i) generator) { + final p = C.std_VecF64_new(length); + for (var i = 0; i < length; i++) { + C.std_VecF64_set(p, i, generator(i)); + } + return VecF64.fromPointer(p, length: length); + } + + static final finalizer = ffi.NativeFinalizer(C.addresses.std_VecF64_free); + + @override + VecF64 clone() => VecF64.fromPointer(C.std_VecF64_clone(ptr)); + + @override + int get length => C.std_VecF64_length(ptr); + + ffi.Pointer get dataPtr => C.std_VecF64_data(ptr); + + Float64List get data => dataPtr.cast().asTypedList(length); + + @override + Iterator get iterator => VecF64Iterator(data); + + @override + void dispose() { + finalizer.detach(this); + C.std_VecF64_free(ptr); + } + + @override + ffi.Pointer asVoid() => dataPtr.cast(); + + @override + void operator []=(int idx, double value) => data[idx] = value; + + @override + double operator [](int idx) => data[idx]; + + @override + void add(double element) => C.std_VecF64_push_back(ptr, element); + + @override + void clear() => C.std_VecF64_clear(ptr); + + @override + void extend(Vec other) => C.std_VecF64_extend(ptr, (other as VecF64).ptr); + + @override + void reserve(int newCapacity) => C.std_VecF64_reserve(ptr, newCapacity); + + @override + void resize(int newSize) => C.std_VecF64_resize(ptr, newSize); + + @override + void shrinkToFit() => C.std_VecF64_shrink_to_fit(ptr); + + @override + int size() => C.std_VecF64_length(ptr); +} + +class VecF64Iterator extends VecIterator { + VecF64Iterator(this.data); + Float64List data; + + @override + int get length => data.length; + + @override + double operator [](int idx) => data[idx]; +} + +extension StringVecExtension on String { + VecU8 get u8 { + final p = toNativeUtf8(); + final pp = p.cast().asTypedList(p.length); + final v = VecU8.fromList(pp); + calloc.free(p); + return v; + } + + VecI8 get i8 { + final p = toNativeUtf8(); + final pp = p.cast().asTypedList(p.length); + final v = VecI8.fromList(pp); + calloc.free(p); + return v; + } +} + +extension ListUCharExtension on List { + VecU8 get vecUChar => VecU8.fromList(this); + VecI8 get vecChar => VecI8.fromList(this); + VecU8 get u8 => VecU8.fromList(this); + VecI8 get i8 => VecI8.fromList(this); + VecU16 get u16 => VecU16.fromList(this); + VecI16 get i16 => VecI16.fromList(this); + VecI32 get i32 => VecI32.fromList(this); + VecF32 get f32 => VecF32.fromList(map((e) => e.toDouble()).toList()); + VecF64 get f64 => VecF64.fromList(map((e) => e.toDouble()).toList()); +} + +extension ListFloatExtension on List { + VecF32 get f32 => VecF32.fromList(this); + VecF64 get f64 => VecF64.fromList(this); +} diff --git a/pubspec.yaml b/pubspec.yaml index 93c821a..dc9798c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: mnn description: A package for running MNN models on Dart and Flutter. version: 0.0.3 -mnn_version: 3.2.1 +mnn_version: 3.2.3 repository: https://github.com/rainyl/mnn.dart environment: @@ -30,3 +30,8 @@ topics: - machine-learning - deep-learning - native-assets + +hooks: + user-defines: + mnn: + build_local: true diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a7f2ed7..6786cb1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,7 +61,7 @@ else() endif() endif() -set(MNNC_LINK_LIBS MNN) +set(MNNC_LINK_LIBS MNN MNN_Express) if (ANDROID) set(MNNC_LINK_LIBS ${MNNC_LINK_LIBS} mediandk -landroid) if(MNN_OPENCL) @@ -105,11 +105,15 @@ elseif (APPLE AND NOT IOS) endif () set(SOURCES - autotime.cpp - interpreter.cpp - tensor.cpp - image_process.cpp - mnn_stb_image.cpp + "base.cpp" + "stdvec.cpp" + "expr.cpp" + "autotime.cpp" + "interpreter.cpp" + "tensor.cpp" + "image_process.cpp" + "mnn_stb_image.cpp" + "expr_op.cpp" ) include_directories( diff --git a/src/MNN/Interpreter.hpp b/src/MNN/Interpreter.hpp index eaf33e9..d25af2e 100644 --- a/src/MNN/Interpreter.hpp +++ b/src/MNN/Interpreter.hpp @@ -216,8 +216,9 @@ class MNN_PUBLIC Interpreter { // Geometry Compute option, default is 0xFFFF GEOMETRY_COMPUTE_MASK = 4, - // 0: Close dynamic quant; + // default 0 // 1: For general convolution, use one scale&zeropoint to quant. + // 2: use block-quant for input data. DYNAMIC_QUANT_OPTIONS = 5, // For Mobile CPU with big-litter core, set decrease rate to let MNN divide task differential by CPU's performance @@ -245,7 +246,16 @@ class MNN_PUBLIC Interpreter { USE_CACHED_MMAP = 12, // Multi-Thread Load module, default is 0 (don't use other Thread) - INIT_THREAD_NUMBER = 13 + INIT_THREAD_NUMBER = 13, + + // Used CPU ids + CPU_CORE_IDS = 14, + + // set CPU threads to use when supports Arm sme2 + CPU_SME2_INSTRUCTIONS = 15, + + // Enable KleidiAI + CPU_ENABLE_KLEIDIAI = 16 }; enum ExternalPathType { @@ -258,6 +268,9 @@ class MNN_PUBLIC Interpreter { // Weight Buffer Cache File EXTERNAL_WEIGHT_DIR = 2, + // Path of the NPU Model directory + EXTERNAL_NPU_FILE_DIR = 3, + // Other types ... }; @@ -280,10 +293,12 @@ class MNN_PUBLIC Interpreter { /** * @brief The API shoud be called before create session. - * @param mode Hint type + * @param hint Hint type * @param value Hint value + * @param size Hint value size(when use a ptr) */ - void setSessionHint(HintMode mode, int value); + void setSessionHint(HintMode hint, int value); + void setSessionHint(HintMode hint, int* value, size_t size); public: /** * @brief create runtimeInfo separately with schedule config. diff --git a/src/MNN/MNNDefine.h b/src/MNN/MNNDefine.h index df93151..cfe1328 100644 --- a/src/MNN/MNNDefine.h +++ b/src/MNN/MNNDefine.h @@ -59,7 +59,7 @@ if(!(success)){ \ MNN_ERROR("Check failed: %s ==> %s\n", #success, #log); \ } - +#ifndef MNN_BUILD_STATIC_LIBS #if defined(_MSC_VER) #if defined(BUILDING_MNN_DLL) #define MNN_PUBLIC __declspec(dllexport) @@ -71,11 +71,13 @@ MNN_ERROR("Check failed: %s ==> %s\n", #success, #log); \ #else #define MNN_PUBLIC __attribute__((visibility("default"))) #endif - +#else +#define MNN_PUBLIC +#endif #define STR_IMP(x) #x #define STR(x) STR_IMP(x) #define MNN_VERSION_MAJOR 3 #define MNN_VERSION_MINOR 2 -#define MNN_VERSION_PATCH 1 +#define MNN_VERSION_PATCH 2 #define MNN_VERSION STR(MNN_VERSION_MAJOR) "." STR(MNN_VERSION_MINOR) "." STR(MNN_VERSION_PATCH) #endif /* MNNDefine_h */ diff --git a/src/MNN/expr/Executor.hpp b/src/MNN/expr/Executor.hpp index c4f9d41..744bc59 100644 --- a/src/MNN/expr/Executor.hpp +++ b/src/MNN/expr/Executor.hpp @@ -27,6 +27,7 @@ struct ExecutorAttr; class MNN_PUBLIC Executor { public: class ComputeCache; + class RuntimeExecuteWrap; struct DebugTools; /**Internal Usage Begin*/ struct Requirement { @@ -126,8 +127,10 @@ class MNN_PUBLIC Executor { friend class Executor; void setMode(Interpreter::SessionMode mode); void setHint(Interpreter::HintMode mode, int value); + void setHint(Interpreter::HintMode mode, int* value, size_t size); void setHintPtr(Interpreter::HintMode mode, void* value); bool getInfo(Interpreter::SessionInfoCode code, void* ptr); + static bool getDeviceInfo(const std::string& deviceKey, const MNNForwardType type, std::string& deviceValue); BackendConfig* getBnConfig(); const RuntimeAttr* getInside() const { return mInside; @@ -139,6 +142,11 @@ class MNN_PUBLIC Executor { RuntimeManager(); }; static bool getComputeInfo(EXPRP expr, Interpreter::SessionInfoCode code, void* ptr); +#ifndef MNN_REDUCE_SIZE + std::map>& subgraph() { + return mSubGraph; + }; +#endif private: std::shared_ptr _getOrCreateRuntime(MNNForwardType type, const BackendConfig* config, int numberThread, bool reset = true); Executor(std::shared_ptr backend, MNNForwardType type, int numberThread); diff --git a/src/MNN/plugin/PluginContext.hpp b/src/MNN/plugin/PluginContext.hpp index 665a3eb..80c10cb 100644 --- a/src/MNN/plugin/PluginContext.hpp +++ b/src/MNN/plugin/PluginContext.hpp @@ -71,7 +71,8 @@ class MNN_PUBLIC CPUKernelContext : public PluginContext { CPUKernelContext(const std::string& op_type, // NOLINT Backend* backend, // NOLINT const std::vector& inputs, // NOLINT - const std::vector& outputs); + const std::vector& outputs, + const std::string& dir_path); virtual ~CPUKernelContext() = default; @@ -83,8 +84,13 @@ class MNN_PUBLIC CPUKernelContext : public PluginContext { return op_type_; } + const std::string& dir_path() const { + return dir_path_; + } + private: const std::string op_type_ = ""; + const std::string dir_path_; Backend* backend_ = nullptr; }; diff --git a/src/base.cpp b/src/base.cpp new file mode 100644 index 0000000..294f3f5 --- /dev/null +++ b/src/base.cpp @@ -0,0 +1,22 @@ +// +// Created by rainy on 2025/9/15. +// + +#include "base.h" +#include + +void *dart_malloc(size_t size) { +#if WIN32 + return CoTaskMemAlloc(size); +#else + return malloc(size); +#endif +} + +void dart_free(void *ptr) { +#if WIN32 + return CoTaskMemFree(ptr); +#else + return free(ptr); +#endif +} diff --git a/src/base.h b/src/base.h new file mode 100644 index 0000000..631c2cb --- /dev/null +++ b/src/base.h @@ -0,0 +1,28 @@ +// +// Created by rainy on 2025/9/15. +// + +#ifndef MNN_C_API_BASE_H +#define MNN_C_API_BASE_H + +#include "mnn_type.h" + +#include + +#if WIN32 +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +MNN_C_API void *dart_malloc(size_t size); + +MNN_C_API void dart_free(void *ptr); + +#ifdef __cplusplus +} +#endif + +#endif // MNN_C_API_BASE_H diff --git a/src/expr.cpp b/src/expr.cpp new file mode 100644 index 0000000..9d310f7 --- /dev/null +++ b/src/expr.cpp @@ -0,0 +1,273 @@ +// +// Created by rainy on 2025/9/10. +// + +#include "expr.h" + +#include "MNN/expr/Expr.hpp" +#include "base.h" +#include +#include +#include +#include + +VecVARP_t mnn_expr_VecVARP_create(size_t length, VARP_t value) { + if (value) return new std::vector(length, *value); + return new std::vector(length); +} + +void mnn_expr_VecVARP_free(void *self) { + delete static_cast(self); + self = nullptr; +} +VARP_t mnn_expr_VecVARP_at(VecVARP_t self, int i) { return new MNN::Express::VARP(self->at(i)); } +VARP_t mnn_expr_VecVARP_at_ref(VecVARP_t self, int i) { return &self->at(i); } +void mnn_expr_VecVARP_set(VecVARP_t self, int i, VARP_t value) { self->at(i) = *value; } +void mnn_expr_VecVARP_push_back(VecVARP_t self, VARP_t value) { return self->push_back(*value); } +size_t mnn_expr_VecVARP_size(VecVARP_t self) { return self->size(); } + +void mnn_expr_VecWeakEXPRP_free(void *self) { delete static_cast(self); } +MNN_C_API EXPRP_t mnn_expr_VecWeakEXPRP_at(VecWeakEXPRP_t self, int i) { + auto _varp = self->at(i); + if (_varp.expired()) return nullptr; + return new MNN::Express::EXPRP(_varp.lock()); +} +MNN_C_API void mnn_expr_VecWeakEXPRP_set(VecWeakEXPRP_t self, int i, EXPRP_t value) { + self->at(i) = *value; +} +MNN_C_API void mnn_expr_VecWeakEXPRP_push_back(VecWeakEXPRP_t self, EXPRP_t value) { + self->push_back(*value); +} +MNN_C_API size_t mnn_expr_VecWeakEXPRP_size(VecWeakEXPRP_t self) { return self->size(); } + +void mnn_expr_Variable_Info_free(void *self) { + auto p = static_cast(self); + if (p != nullptr) { + free(p->dim); + free(p); + } +} + +MNN_C_API VARMAP_t mnn_expr_VARMAP_create() { + return new std::map(); +} +MNN_C_API void mnn_expr_VARMAP_free(void *self) { delete static_cast(self); } +MNN_C_API size_t mnn_expr_VARMAP_size(VARMAP_t self) { return self->size(); } +MNN_C_API char **mnn_expr_VARMAP_keys(VARMAP_t self) { + char **keys = static_cast(dart_malloc(self->size() * sizeof(char *))); + int idx = 0; + for (const auto &pair : *self) { + keys[idx] = strdup(pair.first.c_str()); + idx++; + } + return keys; +} +MNN_C_API VARP_t mnn_expr_VARMAP_get(VARMAP_t self, char *key) { + auto it = self->find(key); + if (it != self->end()) return new MNN::Express::VARP(self->at(key)); + return nullptr; +} +MNN_C_API VARP_t mnn_expr_VARMAP_get_ref(VARMAP_t self, char *key) { + auto it = self->find(key); + if (it != self->end()) return &self->at(key); + return nullptr; +} +MNN_C_API void mnn_expr_VARMAP_set(VARMAP_t self, char *key, VARP_t value) { + self->at(key) = *value; +} + +VARP_t mnn_expr_VARP_create_empty() { return new MNN::Express::VARP(); } +VARP_t mnn_expr_VARP_create_VARP(VARP_t other) { return new MNN::Express::VARP(*other); } +void mnn_expr_VARP_free(void *self) { + delete static_cast(self); + self = nullptr; +} +VARP_t mnn_expr_VARP_op_add(VARP_t self, VARP_t other) { + return new MNN::Express::VARP((*self) + (*other)); +} +VARP_t mnn_expr_VARP_op_sub(VARP_t self, VARP_t other) { + return new MNN::Express::VARP((*self) - (*other)); +} +VARP_t mnn_expr_VARP_op_mul(VARP_t self, VARP_t other) { + return new MNN::Express::VARP((*self) * (*other)); +} +VARP_t mnn_expr_VARP_op_div(VARP_t self, VARP_t other) { + return new MNN::Express::VARP((*self) / (*other)); +} +VARP_t mnn_expr_VARP_mean(VARP_t self, VecI32 dims) { + return new MNN::Express::VARP(self->mean(*dims)); +} +VARP_t mnn_expr_VARP_sum(VARP_t self, VecI32 dims) { + return new MNN::Express::VARP(self->sum(*dims)); +} +bool mnn_expr_VARP_op_eqeq(VARP_t self, VARP_t other) { return (*self) == (*other); } +bool mnn_expr_VARP_op_less(VARP_t self, VARP_t other) { return (*self) < (*other); } +bool mnn_expr_VARP_op_lessequal(VARP_t self, VARP_t other) { return (*self) <= (*other); } +void mnn_expr_VARP_op_assign(VARP_t self, VARP_t other) { (*self) = (*other); } +bool mnn_expr_VARP_fix(VARP_t self, int type) { + return self->fix(static_cast(type)); +} +void mnn_expr_VARP_setOrder(VARP_t self, int format) { + self->setOrder(static_cast(format)); +} + +struct mnn_expr_Variable_Info *mnn_expr_VARP_getInfo(VARP_t self) { + auto _info = (*self)->getInfo(); + if (_info == nullptr) { return nullptr; } + auto info = static_cast(dart_malloc(sizeof(mnn_expr_Variable_Info))); + info->order = static_cast(_info->order); + info->ndim = _info->dim.size(); + auto pdim = static_cast(dart_malloc(info->ndim * sizeof(int32_t))); + for (int i = 0; i < info->ndim; i++) { pdim[i] = _info->dim[i]; } + info->dim = pdim; + info->type = {static_cast(_info->type.code), _info->type.bits, _info->type.lanes}; + info->size = _info->size; + return info; +} + +const void *mnn_expr_VARP_readMap(VARP_t self) { return (*self)->readMap(); } +void *mnn_expr_VARP_writeMap(VARP_t self) { return (*self)->writeMap(); } +void mnn_expr_VARP_unMap(VARP_t self) { (*self)->unMap(); } + +// MNN::Express::Variable +void mnn_expr_VARP_setName(VARP_t self, char *name) { (*self)->setName(name); } +char *mnn_expr_VARP_getName(VARP_t self) { return strdup((*self)->name().c_str()); } +bool mnn_expr_VARP_setDevicePtr(VARP_t self, const void *devicePtr, int memoryType) { + return (*self)->setDevicePtr(devicePtr, memoryType); +} +bool mnn_expr_VARP_copyToDevicePtr(VARP_t self, void *devicePtr, int memoryType) { + return (*self)->copyToDevicePtr(devicePtr, memoryType); +} + +struct Variable_expr_pair *mnn_expr_VARP_getExpr(VARP_t self) { + auto _expr = (*self)->expr(); + auto pair = static_cast(dart_malloc(sizeof(Variable_expr_pair))); + pair->index = _expr.second; + pair->expr = new MNN::Express::EXPRP{_expr.first}; + return pair; +} + +bool mnn_expr_VARP_resize(VARP_t self, VecI32 dims) { return (*self)->resize(*dims); } +void mnn_expr_VARP_writeScaleMap(VARP_t self, float scaleValue, float zeroPoint) { + (*self)->writeScaleMap(scaleValue, zeroPoint); +} +bool mnn_expr_VARP_input(VARP_t self, VARP_t src) { return (*self)->input(*src); } +void mnn_expr_VARP_static_replace(VARP_t dst, VARP_t src) { + MNN::Express::Variable::replace(*dst, *src); +} +VARP_t mnn_expr_VARP_static_create_EXPRP(EXPRP_t expr, int index) { + return new MNN::Express::VARP(MNN::Express::Variable::create(*expr, index)); +} +VecVARP_t mnn_expr_VARP_static_load(const char *fileName) { + auto v = MNN::Express::Variable::load(fileName); + auto rval = new std::vector(v); + return rval; +} + +VARMAP_t mnn_expr_VARP_static_loadMap(const char *fileName) { + auto varmap = MNN::Express::Variable::loadMap(fileName); + return new std::map(varmap); +} + +VecVARP_t mnn_expr_VARP_static_loadBuffer(const uint8_t *buffer, size_t length) { + auto vec = MNN::Express::Variable::load(buffer, length); + return new std::vector(vec); +} + +VARMAP_t mnn_expr_VARP_static_loadMapBuffer(const uint8_t *buffer, size_t length) { + auto varmap = MNN::Express::Variable::loadMap(buffer, length); + return new std::map(varmap); +} + +void mnn_expr_VARP_static_save(VecVARP_t vars, const char *fileName) { + MNN::Express::Variable::save(*vars, fileName); +} + +VecI8 mnn_expr_VARP_static_saveBytes(VecVARP_t vars) { + return new std::vector(MNN::Express::Variable::save(*vars)); +} + +void mnn_expr_VARP_static_saveNet(VecVARP_t vars, Net_t dest) { + MNN::Express::Variable::save(*vars, dest); +} + +void mnn_expr_VARP_static_prepareCompute(VecVARP_t vars, bool forceCPU) { + MNN::Express::Variable::prepareCompute(*vars, forceCPU); +} +void mnn_expr_VARP_static_compute(VecVARP_t vars, bool forceCPU) { + MNN::Express::Variable::compute(*vars, forceCPU); +} +size_t mnn_expr_VARP_linkNumber(VARP_t self) { return (*self)->linkNumber(); } +const VecWeakEXPRP_t mnn_expr_VARP_toExprs(VARP_t self) { + auto exprs = (*self)->toExprs(); + return new std::vector>(exprs); +} +void mnn_expr_VARP_setExpr(VARP_t self, EXPRP_t expr, int index) { (*self)->setExpr(*expr, index); } +const mnn_tensor_t mnn_expr_VARP_getTensor(VARP_t self) { + return new MNN::Tensor((*self)->getTensor()); +} + +EXPRP_t mnn_expr_Expr_create_empty() { return new std::shared_ptr(); } +EXPRP_t mnn_expr_Expr_static_create(mnn_tensor_t tensor, bool own) { + return new MNN::Express::EXPRP(MNN::Express::Expr::create(tensor, own)); +} +EXPRP_t mnn_expr_Expr_static_create_1( + struct mnn_expr_Variable_Info *info, const void *ptr, int type, int memoryType +) { + MNN::Express::Variable::Info _info; + _info.order = static_cast(info->order); + _info.dim = std::vector(info->dim, info->dim + info->ndim); + _info.type = + halide_type_t((halide_type_code_t)info->type.code, info->type.bits, info->type.lanes); + _info.size = info->size; + return new MNN::Express::EXPRP( + MNN::Express::Expr::create( + std::move(_info), + ptr, + static_cast(type), + static_cast(memoryType) + ) + ); +} +EXPRP_t mnn_expr_Expr_static_create_2(OpT_t op, VecVARP_t inputs, int outputSize) { + return new MNN::Express::EXPRP(MNN::Express::Expr::create(op, *inputs, outputSize)); +} + +void mnn_expr_Expr_free(EXPRP_t self) { delete self; } + +void mnn_expr_Expr_setName(EXPRP_t self, const char *name) { self->get()->setName(name); } +const char *mnn_expr_Expr_getName(EXPRP_t self) { return strdup(self->get()->name().c_str()); } +const Op_t mnn_expr_Expr_getOp(EXPRP_t self) { return const_cast(self->get()->get()); } +VecVARP_t mnn_expr_Expr_getInputs(EXPRP_t self) { + auto _inputs = self->get()->inputs(); + return new std::vector(_inputs); +} + +VecWeakEXPRP_t mnn_expr_Expr_getOutputs(EXPRP_t self) { + auto vec = self->get()->outputs(); + return new std::vector>(vec); +} + +int mnn_expr_Expr_getOutputSize(EXPRP_t self) { return self->get()->outputSize(); } +const char *mnn_expr_Expr_getOutputName(EXPRP_t self, int index) { + return strdup(self->get()->outputName(index).c_str()); +} +void mnn_expr_Expr_static_replace(EXPRP_t oldExpr, EXPRP_t newExpr) { + MNN::Express::Expr::replace(*oldExpr, *newExpr); +} +bool mnn_expr_Expr_requireInfo(EXPRP_t self) { return self->get()->requireInfo(); } + +int mnn_expr_Expr_inputType(EXPRP_t self) { return static_cast(self->get()->inputType()); } + +struct mnn_expr_Variable_Info *mnn_expr_Expr_outputInfo(EXPRP_t self, int index) { + auto _info = self->get()->outputInfo(index); + auto info = static_cast(dart_malloc(sizeof(mnn_expr_Variable_Info))); + info->order = static_cast(_info->order); + info->ndim = _info->dim.size(); + auto pdim = static_cast(dart_malloc(info->ndim * sizeof(int32_t))); + for (int i = 0; i < info->ndim; i++) { pdim[i] = _info->dim[i]; } + info->dim = pdim; + info->type = {static_cast(_info->type.code), _info->type.bits, _info->type.lanes}; + info->size = _info->size; + return info; +} diff --git a/src/expr.h b/src/expr.h new file mode 100644 index 0000000..3f4af5b --- /dev/null +++ b/src/expr.h @@ -0,0 +1,154 @@ +#ifndef MNN_EXPR_H +#define MNN_EXPR_H + +#include "base.h" +#include "error_code.h" +#include "mnn_type.h" +#include "stdvec.h" +#include "tensor.h" +#include + +#ifdef __cplusplus +#include "MNN/expr/Expr.hpp" +extern "C" { +#endif + +/** Opaque pointer types */ +#ifdef __cplusplus +typedef MNN::Express::VARP *VARP_t; +typedef MNN::Express::EXPRP *EXPRP_t; +typedef MNN::Express::VARPS *VecVARP_t; +typedef std::vector *VecWeakEXPRP_t; +typedef MNN::OpT *OpT_t; +typedef MNN::Op *Op_t; +typedef std::pair< + std::map, + std::map> *VARMAP_PAIR_t; +typedef std::map *VARMAP_t; +typedef MNN::NetT *Net_t; +#else +typedef void *VARP_t; +typedef void *EXPRP_t; +typedef void *VecVARP_t; +typedef void *VecWeakEXPRP_t; +typedef void *mnn_expr_Expr_t; +typedef void *OpT_t; +typedef void *Op_t; +typedef void *VARMAP_PAIR_t; +typedef void *VARMAP_t; +typedef void *Net_t; +#endif + +struct mnn_expr_Variable_Info { + int order; + int32_t *dim; + size_t ndim; + halide_type_c_t type; + size_t size; +}; + +struct Variable_expr_pair { + EXPRP_t expr; + int index; +}; + +MNN_C_API VecVARP_t mnn_expr_VecVARP_create(size_t length, VARP_t value); +MNN_C_API void mnn_expr_VecVARP_free(void *self); +MNN_C_API VARP_t mnn_expr_VecVARP_at(VecVARP_t self, int i); +MNN_C_API VARP_t mnn_expr_VecVARP_at_ref(VecVARP_t self, int i); +MNN_C_API void mnn_expr_VecVARP_set(VecVARP_t self, int i, VARP_t value); +MNN_C_API void mnn_expr_VecVARP_push_back(VecVARP_t self, VARP_t value); +MNN_C_API size_t mnn_expr_VecVARP_size(VecVARP_t self); + +MNN_C_API void mnn_expr_VecWeakEXPRP_free(void *self); +MNN_C_API EXPRP_t mnn_expr_VecWeakEXPRP_at(VecWeakEXPRP_t self, int i); +MNN_C_API void mnn_expr_VecWeakEXPRP_set(VecWeakEXPRP_t self, int i, EXPRP_t value); +MNN_C_API void mnn_expr_VecWeakEXPRP_push_back(VecWeakEXPRP_t self, EXPRP_t value); +MNN_C_API size_t mnn_expr_VecWeakEXPRP_size(VecWeakEXPRP_t self); + +MNN_C_API void mnn_expr_Variable_Info_free(void *self); + +MNN_C_API VARMAP_t mnn_expr_VARMAP_create(); +MNN_C_API void mnn_expr_VARMAP_free(void *self); +MNN_C_API size_t mnn_expr_VARMAP_size(VARMAP_t self); +MNN_C_API char **mnn_expr_VARMAP_keys(VARMAP_t self); +MNN_C_API VARP_t mnn_expr_VARMAP_get(VARMAP_t self, char *key); +MNN_C_API VARP_t mnn_expr_VARMAP_get_ref(VARMAP_t self, char *key); +MNN_C_API void mnn_expr_VARMAP_set(VARMAP_t self, char *key, VARP_t value); + +// MNN::Express::VARP +MNN_C_API VARP_t mnn_expr_VARP_create_empty(); +MNN_C_API VARP_t mnn_expr_VARP_create_VARP(VARP_t other); +MNN_C_API void mnn_expr_VARP_free(void *self); +MNN_C_API VARP_t mnn_expr_VARP_op_add(VARP_t self, VARP_t other); +MNN_C_API VARP_t mnn_expr_VARP_op_sub(VARP_t self, VARP_t other); +MNN_C_API VARP_t mnn_expr_VARP_op_mul(VARP_t self, VARP_t other); +MNN_C_API VARP_t mnn_expr_VARP_op_div(VARP_t self, VARP_t other); +MNN_C_API VARP_t mnn_expr_VARP_mean(VARP_t self, VecI32 dims); +MNN_C_API VARP_t mnn_expr_VARP_sum(VARP_t self, VecI32 dims); +MNN_C_API bool mnn_expr_VARP_op_eqeq(VARP_t self, VARP_t other); +MNN_C_API bool mnn_expr_VARP_op_less(VARP_t self, VARP_t other); +MNN_C_API bool mnn_expr_VARP_op_lessequal(VARP_t self, VARP_t other); +MNN_C_API void mnn_expr_VARP_op_assign(VARP_t self, VARP_t other); +MNN_C_API bool mnn_expr_VARP_fix(VARP_t self, int type); // InputType type +MNN_C_API void mnn_expr_VARP_setOrder(VARP_t self, int format); // Dimensionformat format +MNN_C_API struct mnn_expr_Variable_Info *mnn_expr_VARP_getInfo(VARP_t self); +MNN_C_API const void *mnn_expr_VARP_readMap(VARP_t self); +MNN_C_API void *mnn_expr_VARP_writeMap(VARP_t self); +MNN_C_API void mnn_expr_VARP_unMap(VARP_t self); + +// MNN::Express::Variable +MNN_C_API void mnn_expr_VARP_setName(VARP_t self, char *name); +MNN_C_API char *mnn_expr_VARP_getName(VARP_t self); +MNN_C_API bool mnn_expr_VARP_setDevicePtr(VARP_t self, const void *devicePtr, int memoryType); +MNN_C_API bool mnn_expr_VARP_copyToDevicePtr(VARP_t self, void *devicePtr, int memoryType); +MNN_C_API struct Variable_expr_pair *mnn_expr_VARP_getExpr(VARP_t self); +MNN_C_API bool mnn_expr_VARP_resize(VARP_t self, VecI32 dims); +MNN_C_API void mnn_expr_VARP_writeScaleMap(VARP_t self, float scaleValue, float zeroPoint); +MNN_C_API bool mnn_expr_VARP_input(VARP_t self, VARP_t src); +MNN_C_API void mnn_expr_VARP_static_replace(VARP_t dst, VARP_t src); +MNN_C_API VARP_t mnn_expr_VARP_static_create_EXPRP(EXPRP_t expr, int index); + +MNN_C_API VecVARP_t mnn_expr_VARP_static_load(const char *fileName); +MNN_C_API VARMAP_t mnn_expr_VARP_static_loadMap(const char *fileName); +MNN_C_API VecVARP_t mnn_expr_VARP_static_loadBuffer(const uint8_t *buffer, size_t length); +MNN_C_API VARMAP_t mnn_expr_VARP_static_loadMapBuffer(const uint8_t *buffer, size_t length); +// MNN_C_API void mnn_expr_VARP_static_getExecuteOrder(VecVARP_t output); +MNN_C_API void mnn_expr_VARP_static_save(VecVARP_t vars, const char *fileName); +MNN_C_API VecI8 mnn_expr_VARP_static_saveBytes(VecVARP_t vars); +MNN_C_API void mnn_expr_VARP_static_saveNet(VecVARP_t vars, Net_t dest); + +MNN_C_API void mnn_expr_VARP_static_prepareCompute(VecVARP_t vars, bool forceCPU); +MNN_C_API void mnn_expr_VARP_static_compute(VecVARP_t vars, bool forceCPU); +MNN_C_API size_t mnn_expr_VARP_linkNumber(VARP_t self); +MNN_C_API const VecWeakEXPRP_t mnn_expr_VARP_toExprs(VARP_t self); +MNN_C_API void mnn_expr_VARP_setExpr(VARP_t self, EXPRP_t expr, int index); +MNN_C_API const mnn_tensor_t mnn_expr_VARP_getTensor(VARP_t self); + +// MNN::Express::Expr +MNN_C_API EXPRP_t mnn_expr_Expr_create_empty(); +MNN_C_API EXPRP_t mnn_expr_Expr_static_create(mnn_tensor_t tensor, bool own); +MNN_C_API EXPRP_t mnn_expr_Expr_static_create_1( + struct mnn_expr_Variable_Info *info, const void *ptr, int type, int memoryType +); +MNN_C_API EXPRP_t mnn_expr_Expr_static_create_2(OpT_t op, VecVARP_t inputs, int outputSize); +MNN_C_API void mnn_expr_Expr_free(EXPRP_t self); + +MNN_C_API void mnn_expr_Expr_setName(EXPRP_t self, const char *name); +MNN_C_API const Op_t mnn_expr_Expr_getOp(EXPRP_t self); +MNN_C_API VecVARP_t mnn_expr_Expr_getInputs(EXPRP_t self); +MNN_C_API VecWeakEXPRP_t mnn_expr_Expr_getOutputs(EXPRP_t self); +MNN_C_API int mnn_expr_Expr_getOutputSize(EXPRP_t self); +MNN_C_API void mnn_expr_Expr_static_replace(EXPRP_t oldExpr, EXPRP_t newExpr); +MNN_C_API bool mnn_expr_Expr_requireInfo(EXPRP_t self); +MNN_C_API const char *mnn_expr_Expr_getName(EXPRP_t self); +MNN_C_API const char *mnn_expr_Expr_getOutputName(EXPRP_t self, int index); +MNN_C_API int mnn_expr_Expr_inputType(EXPRP_t self); +// MNN_C_API void mnn_expr_Expr_visitOutputs(); +MNN_C_API struct mnn_expr_Variable_Info *mnn_expr_Expr_outputInfo(EXPRP_t self, int index); + +#ifdef __cplusplus +} +#endif + +#endif // MNN_EXPR_H diff --git a/src/expr_op.cpp b/src/expr_op.cpp new file mode 100644 index 0000000..48b7e66 --- /dev/null +++ b/src/expr_op.cpp @@ -0,0 +1,804 @@ +// +// Created by rainy on 2025/9/11. +// + +#include "expr_op.h" +#include "MNN/expr/MathOp.hpp" +#include "MNN/expr/NeuralNetWorkOp.hpp" + +// Math Op +// BinaryOPs +VARP_t mnn_expr_Add(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Add(*x, *y)); +} +VARP_t mnn_expr_Subtract(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Subtract(*x, *y)); +} +VARP_t mnn_expr_Multiply(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Multiply(*x, *y)); +} +VARP_t mnn_expr_Divide(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Divide(*x, *y)); +} +VARP_t mnn_expr_Pow(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Pow(*x, *y)); +} +VARP_t mnn_expr_Minimum(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Minimum(*x, *y)); +} +VARP_t mnn_expr_Maximum(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Maximum(*x, *y)); +} +VARP_t mnn_expr_BiasAdd(VARP_t value, VARP_t bias) { + return new MNN::Express::VARP(MNN::Express::_BiasAdd(*value, *bias)); +} +VARP_t mnn_expr_Greater(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Greater(*x, *y)); +} +VARP_t mnn_expr_GreaterEqual(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_GreaterEqual(*x, *y)); +} +VARP_t mnn_expr_Less(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Less(*x, *y)); +} +VARP_t mnn_expr_FloorDiv(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_FloorDiv(*x, *y)); +} +VARP_t mnn_expr_SquaredDifference(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_SquaredDifference(*x, *y)); +} +VARP_t mnn_expr_Equal(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Equal(*x, *y)); +} +VARP_t mnn_expr_LessEqual(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_LessEqual(*x, *y)); +} +VARP_t mnn_expr_FloorMod(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_FloorMod(*x, *y)); +} +VARP_t mnn_expr_Atan2(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Atan2(*x, *y)); +} +VARP_t mnn_expr_LogicalOr(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_LogicalOr(*x, *y)); +} +VARP_t mnn_expr_NotEqual(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_NotEqual(*x, *y)); +} +VARP_t mnn_expr_BitwiseAnd(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_BitwiseAnd(*x, *y)); +} +VARP_t mnn_expr_BitwiseOr(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_BitwiseOr(*x, *y)); +} +VARP_t mnn_expr_BitwiseXor(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_BitwiseXor(*x, *y)); +} + +// UnaryOPs +VARP_t mnn_expr_Sign(VARP_t a) { return new MNN::Express::VARP(MNN::Express::_Sign(*a)); } +VARP_t mnn_expr_Abs(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Abs(*x)); } +VARP_t mnn_expr_Negative(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Negative(*x)); } +VARP_t mnn_expr_Floor(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Floor(*x)); } +VARP_t mnn_expr_Round(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Round(*x)); } +VARP_t mnn_expr_Ceil(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Ceil(*x)); } +VARP_t mnn_expr_Square(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Square(*x)); } +VARP_t mnn_expr_Sqrt(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Sqrt(*x)); } +VARP_t mnn_expr_Rsqrt(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Rsqrt(*x)); } +VARP_t mnn_expr_Exp(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Exp(*x)); } +VARP_t mnn_expr_Log(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Log(*x)); } +VARP_t mnn_expr_Sin(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Sin(*x)); } +VARP_t mnn_expr_Sinh(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Sinh(*x)); } +VARP_t mnn_expr_Cos(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Cos(*x)); } +VARP_t mnn_expr_Cosh(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Cosh(*x)); } +VARP_t mnn_expr_Tan(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Tan(*x)); } +VARP_t mnn_expr_Asin(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Asin(*x)); } +VARP_t mnn_expr_Asinh(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Asinh(*x)); } +VARP_t mnn_expr_Acos(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Acos(*x)); } +VARP_t mnn_expr_Acosh(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Acosh(*x)); } +VARP_t mnn_expr_Atan(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Atan(*x)); } +VARP_t mnn_expr_Atanh(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Atanh(*x)); } +VARP_t mnn_expr_Reciprocal(VARP_t x) { + return new MNN::Express::VARP(MNN::Express::_Reciprocal(*x)); +} +VARP_t mnn_expr_Log1p(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Log1p(*x)); } +VARP_t mnn_expr_Gelu(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Gelu(*x)); } +VARP_t mnn_expr_Tanh(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Tanh(*x)); } +VARP_t mnn_expr_Sigmoid(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Sigmoid(*x)); } +VARP_t mnn_expr_Erf(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Erf(*x)); } +VARP_t mnn_expr_Erfc(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Erfc(*x)); } +VARP_t mnn_expr_Erfinv(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Erfinv(*x)); } +VARP_t mnn_expr_Expm1(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Expm1(*x)); } +VARP_t mnn_expr_Hardswish(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Hardswish(*x)); } +VARP_t mnn_expr_Silu(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Silu(*x)); } + +// ReduceOPs +VARP_t mnn_expr_ReduceSum(VARP_t input_variable, VecI32 axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceSum(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceMean(VARP_t input_variable, VecI32 axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceMean(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceMax(VARP_t input_variable, VecI32 axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceMax(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceMin(VARP_t input_variable, VecI32 axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceMin(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceProd(VARP_t input_variable, VecI32 axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceProd(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceAny(VARP_t input_variable, VecI32 axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceAny(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceAll(VARP_t input_variable, VecI32 axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceAll(*input_variable, *axis, keepDims)); +} + +VARP_t mnn_expr_ReduceSumMutable(VARP_t input_variable, VARP_t axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceSumMutable(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceMeanMutable(VARP_t input_variable, VARP_t axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceMeanMutable(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceMaxMutable(VARP_t input_variable, VARP_t axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceMaxMutable(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceMinMutable(VARP_t input_variable, VARP_t axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceMinMutable(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceProdMutable(VARP_t input_variable, VARP_t axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceProdMutable(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceAnyMutable(VARP_t input_variable, VARP_t axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceAnyMutable(*input_variable, *axis, keepDims)); +} +VARP_t mnn_expr_ReduceAllMutable(VARP_t input_variable, VARP_t axis, bool keepDims) { + return new MNN::Express::VARP(MNN::Express::_ReduceAllMutable(*input_variable, *axis, keepDims)); +} + +// EltwiseOPs +VARP_t mnn_expr_Prod(VARP_t a, VARP_t b, float *coeff, size_t coeffSize) { + return new MNN::Express::VARP( + MNN::Express::_Prod(*a, *b, std::vector(coeff, coeff + coeffSize)) + ); +} +VARP_t mnn_expr_Sum(VARP_t a, VARP_t b, float *coeff, size_t coeffSize) { + return new MNN::Express::VARP( + MNN::Express::_Sum(*a, *b, std::vector(coeff, coeff + coeffSize)) + ); +} +VARP_t mnn_expr_Max(VARP_t a, VARP_t b, float *coeff, size_t coeffSize) { + return new MNN::Express::VARP( + MNN::Express::_Max(*a, *b, std::vector(coeff, coeff + coeffSize)) + ); +} +VARP_t mnn_expr_Sub(VARP_t a, VARP_t b, float *coeff, size_t coeffSize) { + return new MNN::Express::VARP( + MNN::Express::_Sub(*a, *b, std::vector(coeff, coeff + coeffSize)) + ); +} +VARP_t mnn_expr_Mod(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_Mod(*x, *y)); +} + +VARP_t mnn_expr_Cast(VARP_t x, halide_type_c_t dtype) { + const auto _dtype = halide_type_t((halide_type_code_t)dtype.code, dtype.bits, dtype.lanes); + return new MNN::Express::VARP(MNN::Express::_Cast(*x, _dtype)); +} +VARP_t mnn_expr_MatMul(VARP_t a, VARP_t b, bool tranposeA, bool tranposeB) { + return new MNN::Express::VARP(MNN::Express::_MatMul(*a, *b, tranposeA, tranposeB)); +} +VARP_t mnn_expr_Normalize( + VARP_t x, + int32_t acrossSpatial, + int32_t channelShared, + float eps, + const float *scale, + size_t scaleLength +) { + return new MNN::Express::VARP( + MNN::Express::_Normalize( + *x, acrossSpatial, channelShared, eps, std::vector(scale, scale + scaleLength) + ) + ); +} +VARP_t mnn_expr_ArgMax(VARP_t input, int axis) { + return new MNN::Express::VARP(MNN::Express::_ArgMax(*input, axis)); +} +VARP_t mnn_expr_ArgMin(VARP_t input, int axis) { + return new MNN::Express::VARP(MNN::Express::_ArgMin(*input, axis)); +} +VARP_t mnn_expr_BatchMatMul(VARP_t x, VARP_t y, bool adj_x, bool adj_y) { + return new MNN::Express::VARP(MNN::Express::_BatchMatMul(*x, *y, adj_x, adj_y)); +} +VARP_t mnn_expr_UnravelIndex(VARP_t indices, VARP_t dims) { + return new MNN::Express::VARP(MNN::Express::_UnravelIndex(*indices, *dims)); +} +VARP_t mnn_expr_ScatterNd(VARP_t indices, VARP_t updates, VARP_t shape) { + return new MNN::Express::VARP(MNN::Express::_ScatterNd(*indices, *updates, *shape)); +} +VARP_t mnn_expr_ScatterNd_1(VARP_t indices, VARP_t updates, VARP_t shape, VARP_t input) { + return new MNN::Express::VARP(MNN::Express::_ScatterNd(*indices, *updates, *shape, *input)); +} +VARP_t mnn_expr_ScatterNd_2(VARP_t indices, VARP_t updates, VARP_t shape, int reduction) { + return new MNN::Express::VARP(MNN::Express::_ScatterNd(*indices, *updates, *shape, reduction)); +} +VARP_t +mnn_expr_ScatterNd_3(VARP_t indices, VARP_t updates, VARP_t shape, VARP_t input, int reduction) { + return new MNN::Express::VARP( + MNN::Express::_ScatterNd(*indices, *updates, *shape, *input, reduction) + ); +} +VARP_t mnn_expr_ScatterElements(VARP_t data, VARP_t indices, VARP_t updates, int reduction) { + return new MNN::Express::VARP( + MNN::Express::_ScatterElements(*data, *indices, *updates, reduction) + ); +} +VARP_t mnn_expr_ScatterElements_1( + VARP_t data, VARP_t indices, VARP_t updates, VARP_t axis, int reduction +) { + return new MNN::Express::VARP( + MNN::Express::_ScatterElements(*data, *indices, *updates, *axis, reduction) + ); +} +VARP_t mnn_expr_OneHot(VARP_t indices, VARP_t depth, VARP_t onValue, VARP_t offValue, int axis) { + return new MNN::Express::VARP(MNN::Express::_OneHot(*indices, *depth, *onValue, *offValue, axis)); +} +VARP_t mnn_expr_BroadcastTo(VARP_t a, VARP_t shape) { + return new MNN::Express::VARP(MNN::Express::_BroadcastTo(*a, *shape)); +} +VARP_t mnn_expr_LinSpace(VARP_t start, VARP_t stop, VARP_t num) { + return new MNN::Express::VARP(MNN::Express::_LinSpace(*start, *stop, *num)); +} +VARP_t mnn_expr_RandomUniform( + VARP_t shape, halide_type_c_t dtype, float low, float high, int seed0, int seed1 +) { + const auto _dtype = halide_type_t((halide_type_code_t)dtype.code, dtype.bits, dtype.lanes); + return new MNN::Express::VARP( + MNN::Express::_RandomUnifom(*shape, _dtype, low, high, seed0, seed1) + ); +} +VARP_t mnn_expr_CumSum(VARP_t x, int axis, bool exclusive, bool reverse) { + return new MNN::Express::VARP(MNN::Express::_CumSum(*x, axis, exclusive, reverse)); +} +VARP_t mnn_expr_CumProd(VARP_t x, int axis) { + return new MNN::Express::VARP(MNN::Express::_CumProd(*x, axis)); +} +VecVARP_t mnn_expr_Svd(VARP_t x) { return new MNN::Express::VARPS(MNN::Express::_Svd(*x)); } +VARP_t mnn_expr_Histogram(VARP_t x, int bin, int min, int max, int channel) { + return new MNN::Express::VARP(MNN::Express::_Histogram(*x, bin, min, max, channel)); +} + +// Neural Network Ops +VARP_t +mnn_expr_Input(const int *shape, size_t shapeLength, int data_format, halide_type_c_t dtype) { + const auto _dtype = halide_type_t((halide_type_code_t)dtype.code, dtype.bits, dtype.lanes); + return new MNN::Express::VARP( + MNN::Express::_Input( + std::vector(shape, shape + shapeLength), + static_cast(data_format), + _dtype + ) + ); +} +VARP_t mnn_expr_Clone(VARP_t source, bool deepCopy) { + return new MNN::Express::VARP(MNN::Express::_Clone(*source, deepCopy)); +} +VARP_t mnn_expr_Scalar(const void *ptr, halide_type_c_t type) { + const auto _dtype = halide_type_t((halide_type_code_t)type.code, type.bits, type.lanes); + return new MNN::Express::VARP(MNN::Express::_Scalar(ptr, _dtype)); +} + +VARP_t mnn_expr_Const( + void *value, const int *shape, size_t shapeLength, int format, halide_type_c_t type +) { + auto _type = halide_type_t((halide_type_code_t)type.code, type.bits, type.lanes); + auto _shape = std::vector(shape, shape + shapeLength); + return new MNN::Express::VARP( + MNN::Express::_Const(value, _shape, static_cast(format), _type) + ); +} + +VARP_t mnn_expr_Conv( + VARP_t weight, + VARP_t bias, + VARP_t x, + int pad, + const int *stride, + size_t strideLength, + const int *dilate, + size_t dilateLength, + int group, + const int *pads, + size_t padsLength +) { + return new MNN::Express::VARP( + MNN::Express::_Conv( + *weight, + *bias, + *x, + static_cast(pad), + std::vector(stride, stride + strideLength), + std::vector(dilate, dilate + dilateLength), + group, + std::vector(pads, pads + padsLength) + ) + ); +} +VARP_t mnn_expr_Deconv( + VARP_t weight, + VARP_t bias, + VARP_t x, + int pad, + const int *stride, + size_t strideLength, + const int *dilate, + size_t dilateLength, + int group, + const int *pads, + size_t padsLength +) { + return new MNN::Express::VARP( + MNN::Express::_Deconv( + *weight, + *bias, + *x, + static_cast(pad), + std::vector(stride, stride + strideLength), + std::vector(dilate, dilate + dilateLength), + group, + std::vector(pads, pads + padsLength) + ) + ); +} +VARP_t mnn_expr_MaxPool( + VARP_t x, + const int *kernel, + size_t kernelLength, + const int *stride, + size_t strideLength, + int pad, + const int *pads, + size_t padsLength +) { + return new MNN::Express::VARP( + MNN::Express::_MaxPool( + *x, + std::vector(kernel, kernel + kernelLength), + std::vector(stride, stride + strideLength), + static_cast(pad), + std::vector(pads, pads + padsLength) + ) + ); +} +VARP_t mnn_expr_AvePool( + VARP_t x, + const int *kernel, + size_t kernelLength, + const int *stride, + size_t strideLength, + int pad, + const int *pads, + size_t padsLength +) { + return new MNN::Express::VARP( + MNN::Express::_AvePool( + *x, + std::vector(kernel, kernel + kernelLength), + std::vector(stride, stride + strideLength), + static_cast(pad), + std::vector(pads, pads + padsLength) + ) + ); +} +VARP_t mnn_expr_Reshape(VARP_t x, const int *shape, size_t shapeLength, int original_format) { + return new MNN::Express::VARP( + MNN::Express::_Reshape( + *x, + std::vector(shape, shape + shapeLength), + static_cast(original_format) + ) + ); +} +VARP_t mnn_expr_Reshape_1(VARP_t x, VARP_t shape) { + return new MNN::Express::VARP(MNN::Express::_Reshape(*x, *shape)); +} +VARP_t mnn_expr_Scale( + VARP_t x, int channels, float *scales, size_t scaleLength, float *bias, size_t biasLength +) { + return new MNN::Express::VARP( + MNN::Express::_Scale( + *x, + channels, + std::vector(scales, scales + scaleLength), + std::vector(bias, bias + biasLength) + ) + ); +} + +VARP_t mnn_expr_Relu(VARP_t x, float slope) { + return new MNN::Express::VARP(MNN::Express::_Relu(*x, slope)); +} +VARP_t mnn_expr_Relu6(VARP_t x, float minValue, float maxValue) { + return new MNN::Express::VARP(MNN::Express::_Relu6(*x, minValue, maxValue)); +} +VARP_t mnn_expr_PRelu(VARP_t x, float *slopes, size_t slopeLength) { + return new MNN::Express::VARP( + MNN::Express::_PRelu(*x, std::vector(slopes, slopes + slopeLength)) + ); +} +VARP_t mnn_expr_Softmax(VARP_t logits, int axis) { + return new MNN::Express::VARP(MNN::Express::_Softmax(*logits, axis)); +} +VARP_t mnn_expr_Softplus(VARP_t features) { + return new MNN::Express::VARP(MNN::Express::_Softplus(*features)); +} +VARP_t mnn_expr_Softsign(VARP_t features) { + return new MNN::Express::VARP(MNN::Express::_Softsign(*features)); +} +VecVARP_t mnn_expr_Split(VARP_t value, const int *size_splits, size_t size_splitsLength, int axis) { + return new MNN::Express::VARPS( + MNN::Express::_Split( + *value, std::vector(size_splits, size_splits + size_splitsLength), axis + ) + ); +} +VARP_t mnn_expr_Slice(VARP_t x, VARP_t starts, VARP_t sizes) { + return new MNN::Express::VARP(MNN::Express::_Slice(*x, *starts, *sizes)); +} +VARP_t mnn_expr_StridedSlice( + VARP_t input, + VARP_t begin, + VARP_t end, + VARP_t strided, + int32_t beginMask, + int32_t endMask, + int32_t ellipsisMask, + int32_t newAxisMask, + int32_t shrinkAxisMask +) { + return new MNN::Express::VARP( + MNN::Express::_StridedSlice( + *input, + *begin, + *end, + *strided, + beginMask, + endMask, + ellipsisMask, + newAxisMask, + shrinkAxisMask + ) + ); +} +VARP_t mnn_expr_StridedSliceWrite( + VARP_t input, + VARP_t begin, + VARP_t end, + VARP_t strided, + VARP_t write, + int32_t beginMask, + int32_t endMask, + int32_t ellipsisMask, + int32_t newAxisMask, + int32_t shrinkAxisMask +) { + return new MNN::Express::VARP( + MNN::Express::_StridedSliceWrite( + *input, + *begin, + *end, + *strided, + *write, + beginMask, + endMask, + ellipsisMask, + newAxisMask, + shrinkAxisMask + ) + ); +} +VARP_t mnn_expr_Concat(VecVARP_t values, int axis) { + return new MNN::Express::VARP(MNN::Express::_Concat(*values, axis)); +} +VARP_t mnn_expr_Convert(VARP_t input, int format) { + return new MNN::Express::VARP( + MNN::Express::_Convert(*input, static_cast(format)) + ); +} +VARP_t mnn_expr_Transpose(VARP_t x, const int *perm, size_t permLength) { + return new MNN::Express::VARP( + MNN::Express::_Transpose(*x, std::vector(perm, perm + permLength)) + ); +} +VARP_t mnn_expr_Transpose_1(VARP_t x, VARP_t perm) { + return new MNN::Express::VARP(MNN::Express::_Transpose(*x, *perm)); +} +VARP_t mnn_expr_ChannelShuffle(VARP_t x, int group) { + return new MNN::Express::VARP(MNN::Express::_ChannelShuffle(*x, group)); +} +VARP_t mnn_expr_ChangeInputFormat(VARP_t input, int format) { + return new MNN::Express::VARP( + MNN::Express::_ChangeInputFormat(*input, static_cast(format)) + ); +} +VARP_t mnn_expr_Reverse(VARP_t x, VARP_t axis) { + return new MNN::Express::VARP(MNN::Express::_Reverse(*x, *axis)); +} +VARP_t mnn_expr_ReverseSequence(VARP_t x, VARP_t y, int batchDim, int seqDim) { + return new MNN::Express::VARP(MNN::Express::_ReverseSequence(*x, *y, batchDim, seqDim)); +} +VARP_t mnn_expr_Crop(VARP_t images, VARP_t size, int axis, const int *offset, size_t offsetLength) { + return new MNN::Express::VARP( + MNN::Express::_Crop(*images, *size, axis, std::vector(offset, offset + offsetLength)) + ); +} +VARP_t mnn_expr_Resize(VARP_t images, float xScale, float yScale) { + return new MNN::Express::VARP(MNN::Express::_Resize(*images, xScale, yScale)); +} +VARP_t mnn_expr_Pad(VARP_t x, VARP_t paddings, int mode) { + return new MNN::Express::VARP( + MNN::Express::_Pad(*x, *paddings, static_cast(mode)) + ); +} +VARP_t mnn_expr_ExpandDims(VARP_t input, int axis) { + return new MNN::Express::VARP(MNN::Express::_ExpandDims(*input, axis)); +} +VARP_t mnn_expr_ExpandDims_1(VARP_t input, VARP_t axis) { + return new MNN::Express::VARP(MNN::Express::_ExpandDims(*input, *axis)); +} +VARP_t mnn_expr_Shape(VARP_t input, bool nchw) { + return new MNN::Express::VARP(MNN::Express::_Shape(*input, nchw)); +} +VARP_t mnn_expr_Stack(VecVARP_t values, int axis) { + return new MNN::Express::VARP(MNN::Express::_Stack(*values, axis)); +} +// enum InterpolationMethod {BILINEAR, NEAREST}; +VARP_t mnn_expr_CropAndResize( + VARP_t image, + VARP_t boxes, + VARP_t box_ind, + VARP_t crop_size, + int method, + float extrapolation_value +) { + return new MNN::Express::VARP( + MNN::Express::_CropAndResize( + *image, + *boxes, + *box_ind, + *crop_size, + static_cast(method), + extrapolation_value + ) + ); +} +VARP_t mnn_expr_Fill(VARP_t dims, VARP_t value) { + return new MNN::Express::VARP(MNN::Express::_Fill(*dims, *value)); +} +VARP_t mnn_expr_Tile(VARP_t input, VARP_t multiples) { + return new MNN::Express::VARP(MNN::Express::_Tile(*input, *multiples)); +} +VARP_t mnn_expr_Gather(VARP_t params, VARP_t indices) { + return new MNN::Express::VARP(MNN::Express::_Gather(*params, *indices)); +} +VARP_t mnn_expr_GatherV2(VARP_t params, VARP_t indices, VARP_t axis) { + return new MNN::Express::VARP(MNN::Express::_GatherV2(*params, *indices, *axis)); +} +VARP_t mnn_expr_Squeeze(VARP_t input, const int *axis, size_t axisLength) { + return new MNN::Express::VARP( + MNN::Express::_Squeeze(*input, std::vector(axis, axis + axisLength)) + ); +} +VARP_t mnn_expr_Unsqueeze(VARP_t input, const int *axis, size_t axisLength) { + return new MNN::Express::VARP( + MNN::Express::_Unsqueeze(*input, std::vector(axis, axis + axisLength)) + ); +} +VARP_t mnn_expr_BatchToSpaceND(VARP_t input, VARP_t block_shape, VARP_t crops) { + return new MNN::Express::VARP(MNN::Express::_BatchToSpaceND(*input, *block_shape, *crops)); +} +VARP_t mnn_expr_GatherND(VARP_t params, VARP_t indices) { + return new MNN::Express::VARP(MNN::Express::_GatherND(*params, *indices)); +} +VARP_t mnn_expr_GatherElements(VARP_t params, VARP_t indices) { + return new MNN::Express::VARP(MNN::Express::_GatherElements(*params, *indices)); +} +VARP_t mnn_expr_GatherElements_1(VARP_t params, VARP_t indices, VARP_t axis) { + return new MNN::Express::VARP(MNN::Express::_GatherElements(*params, *indices, *axis)); +} +VARP_t mnn_expr_Selu(VARP_t features, float scale, float alpha) { + return new MNN::Express::VARP(MNN::Express::_Selu(*features, scale, alpha)); +} +VARP_t mnn_expr_Size(VARP_t input) { return new MNN::Express::VARP(MNN::Express::_Size(*input)); } +VARP_t mnn_expr_Elu(VARP_t features, float alpha) { + return new MNN::Express::VARP(MNN::Express::_Elu(*features, alpha)); +} +VARP_t mnn_expr_Threshold(VARP_t features, float alpha) { + return new MNN::Express::VARP(MNN::Express::_Threshold(*features, alpha)); +} +VARP_t mnn_expr_MatrixBandPart(VARP_t input, VARP_t num_lower, VARP_t num_upper) { + return new MNN::Express::VARP(MNN::Express::_MatrixBandPart(*input, *num_lower, *num_upper)); +} +VecVARP_t +mnn_expr_Moments(VARP_t x, const int *axis, size_t axisLength, VARP_t shift, bool keepDims) { + return new MNN::Express::VARPS( + MNN::Express::_Moments(*x, std::vector(axis, axis + axisLength), *shift, keepDims) + ); +} +VARP_t mnn_expr_SetDiff1D(VARP_t x, VARP_t y) { + return new MNN::Express::VARP(MNN::Express::_SetDiff1D(*x, *y)); +} +VARP_t mnn_expr_SpaceToDepth(VARP_t input, int block_size) { + return new MNN::Express::VARP(MNN::Express::_SpaceToDepth(*input, block_size)); +} +VARP_t mnn_expr_SpaceToBatchND(VARP_t input, VARP_t block_shape, VARP_t paddings) { + return new MNN::Express::VARP(MNN::Express::_SpaceToBatchND(*input, *block_shape, *paddings)); +} +VARP_t mnn_expr_ZerosLike(VARP_t input) { + return new MNN::Express::VARP(MNN::Express::_ZerosLike(*input)); +} +VecVARP_t mnn_expr_Unstack(VARP_t value, int axis) { + return new MNN::Express::VARPS(MNN::Express::_Unstack(*value, axis)); +} +VARP_t mnn_expr_Rank(VARP_t input) { return new MNN::Express::VARP(MNN::Express::_Rank(*input)); } +VARP_t mnn_expr_Range(VARP_t start, VARP_t limit, VARP_t delta) { + return new MNN::Express::VARP(MNN::Express::_Range(*start, *limit, *delta)); +} +VARP_t mnn_expr_DepthToSpace(VARP_t input, int block_size) { + return new MNN::Express::VARP(MNN::Express::_DepthToSpace(*input, block_size)); +} + +VARP_t mnn_expr_Permute(VARP_t input, const int *dims, size_t dimsLength) { + return new MNN::Express::VARP( + MNN::Express::_Permute(*input, std::vector(dims, dims + dimsLength)) + ); +} +VARP_t mnn_expr_Interp( + VecVARP_t xs, + float widthScale, + float heightScale, + int outputWidth, + int outputHeight, + int resizeType, + bool alignCorners +) { + return new MNN::Express::VARP( + MNN::Express::_Interp( + *xs, widthScale, heightScale, outputWidth, outputHeight, resizeType, alignCorners + ) + ); +} +VARP_t mnn_expr_ZeroGrad(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_ZeroGrad(*x)); } +VARP_t mnn_expr_CosineSimilarity(VARP_t input0, VARP_t input1, VARP_t inputDim) { + return new MNN::Express::VARP(MNN::Express::_CosineSimilarity(*input0, *input1, *inputDim)); +} +// enum GridSamplePaddingMode {GRID_SAMPLE_PADDING_ZEROS, GRID_SAMPLE_PADDING_BORDER, +// GRID_SAMPLE_PADDING_REFLECTION}; +VARP_t +mnn_expr_GridSample(VARP_t input, VARP_t grid, int mode, int paddingMode, bool alignCorners) { + return new MNN::Express::VARP( + MNN::Express::_GridSample( + *input, + *grid, + static_cast(mode), + static_cast(paddingMode), + alignCorners + ) + ); +} +VARP_t mnn_expr_FloatToInt8(VARP_t x, VARP_t scale, char minValue, char maxValue) { + return new MNN::Express::VARP(MNN::Express::_FloatToInt8(*x, *scale, minValue, maxValue)); +} +VARP_t +mnn_expr_FloatToInt8_1(VARP_t x, VARP_t scale, int8_t minValue, int8_t maxValue, int8_t zeroPoint) { + return new MNN::Express::VARP( + MNN::Express::_FloatToInt8(*x, *scale, minValue, maxValue, zeroPoint) + ); +} +VARP_t mnn_expr_Int8ToFloat(VARP_t x, VARP_t scale) { + return new MNN::Express::VARP(MNN::Express::_Int8ToFloat(*x, *scale)); +} +VARP_t mnn_expr_Int8ToFloat_1(VARP_t x, VARP_t scale, int8_t zeroPoint) { + return new MNN::Express::VARP(MNN::Express::_Int8ToFloat(*x, *scale, zeroPoint)); +} + +VARP_t mnn_expr_Select(VARP_t select, VARP_t input0, VARP_t input1) { + return new MNN::Express::VARP(MNN::Express::_Select(*select, *input0, *input1)); +} +VecVARP_t mnn_expr_TopKV2(VARP_t input0, VARP_t input1) { + return new MNN::Express::VARPS(MNN::Express::_TopKV2(*input0, *input1)); +} +// MNN_PUBLIC VARP _ImageProcess(VARP input, CV::ImageProcess::Config config, CV::Matrix matrix, int +// oh, int ow, int oc, int dtype, uint8_t padVal = 0); mnn_expr_VARP_t +// mnn_expr_ImageProcess(mnn_expr_VARP_t input, CV::ImageProcess::Config config, CV::Matrix matrix, +// int oh, int ow, int oc, int dtype, uint8_t padVal); +VARP_t mnn_expr_Where(VARP_t x) { return new MNN::Express::VARP(MNN::Express::_Where(*x)); } +VARP_t mnn_expr_Sort(VARP_t x, int axis, bool arg, bool descend) { + return new MNN::Express::VARP(MNN::Express::_Sort(*x, axis, arg, descend)); +} +VARP_t mnn_expr_Raster( + VecVARP_t vars, const int *regions, size_t regionsLength, const int *shape, size_t shapeLength +) { + return new MNN::Express::VARP( + MNN::Express::_Raster( + *vars, + std::vector(regions, regions + regionsLength), + std::vector(shape, shape + shapeLength) + ) + ); +} +VARP_t mnn_expr_RasterRaw( + VecVARP_t vars, + const int *region, + size_t regionLength, + const int *shape, + size_t shapeLength, + halide_type_t dataType, + int format +) { + const auto _dtype = + halide_type_t((halide_type_code_t)dataType.code, dataType.bits, dataType.lanes); + return new MNN::Express::VARP( + MNN::Express::_RasterRaw( + *vars, + std::vector(region, region + regionLength), + std::vector(shape, shape + shapeLength), + _dtype, + static_cast(format) + ) + ); +} + +VARP_t mnn_expr_Nms( + VARP_t boxes, VARP_t scores, int maxDetections, float iouThreshold, float scoreThreshold +) { + return new MNN::Express::VARP( + MNN::Express::_Nms(*boxes, *scores, maxDetections, iouThreshold, scoreThreshold) + ); +} +VARP_t mnn_expr_Im2Col( + VARP_t x, + const int *kernelSize, + size_t kernelSizeLength, + const int *dilate, + size_t dilateLength, + const int *pads, + size_t padsLength, + const int *stride, + size_t strideLength +) { + return new MNN::Express::VARP( + MNN::Express::_Im2Col( + *x, + std::vector(kernelSize, kernelSize + kernelSizeLength), + std::vector(dilate, dilate + dilateLength), + std::vector(pads, pads + padsLength), + std::vector(stride, stride + strideLength) + ) + ); +} +VARP_t mnn_expr_Col2Im( + VARP_t x, + VARP_t outputShape, + const int *kernelSize, + size_t kernelSizeLength, + const int *dilate, + size_t dilateLength, + const int *pads, + size_t padsLength, + const int *stride, + size_t strideLength +) { + return new MNN::Express::VARP( + MNN::Express::_Col2Im( + *x, + *outputShape, + std::vector(kernelSize, kernelSize + kernelSizeLength), + std::vector(dilate, dilate + dilateLength), + std::vector(pads, pads + padsLength), + std::vector(stride, stride + strideLength) + ) + ); +} diff --git a/src/expr_op.h b/src/expr_op.h new file mode 100644 index 0000000..64bb89f --- /dev/null +++ b/src/expr_op.h @@ -0,0 +1,424 @@ +// +// Created by rainy on 2025/9/11. +// + +#ifndef MNN_EXPR_OP_H +#define MNN_EXPR_OP_H + +#include "expr.h" +#include "mnn_type.h" + +#ifdef __cplusplus +#include "MNN/expr/Expr.hpp" +extern "C" { +#endif +// Math Op +// BinaryOPs +MNN_C_API VARP_t mnn_expr_Add(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Subtract(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Multiply(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Divide(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Pow(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Minimum(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Maximum(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_BiasAdd(VARP_t value, VARP_t bias); +MNN_C_API VARP_t mnn_expr_Greater(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_GreaterEqual(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Less(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_FloorDiv(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_SquaredDifference(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Equal(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_LessEqual(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_FloorMod(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_Atan2(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_LogicalOr(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_NotEqual(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_BitwiseAnd(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_BitwiseOr(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_BitwiseXor(VARP_t x, VARP_t y); + +// UnaryOPs +MNN_C_API VARP_t mnn_expr_Sign(VARP_t a); +MNN_C_API VARP_t mnn_expr_Abs(VARP_t x); +MNN_C_API VARP_t mnn_expr_Negative(VARP_t x); +MNN_C_API VARP_t mnn_expr_Floor(VARP_t x); +MNN_C_API VARP_t mnn_expr_Round(VARP_t x); +MNN_C_API VARP_t mnn_expr_Ceil(VARP_t x); +MNN_C_API VARP_t mnn_expr_Square(VARP_t x); +MNN_C_API VARP_t mnn_expr_Sqrt(VARP_t x); +MNN_C_API VARP_t mnn_expr_Rsqrt(VARP_t x); +MNN_C_API VARP_t mnn_expr_Exp(VARP_t x); +MNN_C_API VARP_t mnn_expr_Log(VARP_t x); +MNN_C_API VARP_t mnn_expr_Sin(VARP_t x); +MNN_C_API VARP_t mnn_expr_Sinh(VARP_t x); +MNN_C_API VARP_t mnn_expr_Cos(VARP_t x); +MNN_C_API VARP_t mnn_expr_Cosh(VARP_t x); +MNN_C_API VARP_t mnn_expr_Tan(VARP_t x); +MNN_C_API VARP_t mnn_expr_Asin(VARP_t x); +MNN_C_API VARP_t mnn_expr_Asinh(VARP_t x); +MNN_C_API VARP_t mnn_expr_Acos(VARP_t x); +MNN_C_API VARP_t mnn_expr_Acosh(VARP_t x); +MNN_C_API VARP_t mnn_expr_Atan(VARP_t x); +MNN_C_API VARP_t mnn_expr_Atanh(VARP_t x); +MNN_C_API VARP_t mnn_expr_Reciprocal(VARP_t x); +MNN_C_API VARP_t mnn_expr_Log1p(VARP_t x); +MNN_C_API VARP_t mnn_expr_Gelu(VARP_t x); +MNN_C_API VARP_t mnn_expr_Tanh(VARP_t x); +MNN_C_API VARP_t mnn_expr_Sigmoid(VARP_t x); +MNN_C_API VARP_t mnn_expr_Erf(VARP_t x); +MNN_C_API VARP_t mnn_expr_Erfc(VARP_t x); +MNN_C_API VARP_t mnn_expr_Erfinv(VARP_t x); +MNN_C_API VARP_t mnn_expr_Expm1(VARP_t x); +MNN_C_API VARP_t mnn_expr_Hardswish(VARP_t x); +MNN_C_API VARP_t mnn_expr_Silu(VARP_t x); + +// ReduceOPs +MNN_C_API VARP_t mnn_expr_ReduceSum(VARP_t input_variable, VecI32 axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceMean(VARP_t input_variable, VecI32 axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceMax(VARP_t input_variable, VecI32 axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceMin(VARP_t input_variable, VecI32 axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceProd(VARP_t input_variable, VecI32 axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceAny(VARP_t input_variable, VecI32 axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceAll(VARP_t input_variable, VecI32 axis, bool keepDims); + +MNN_C_API VARP_t mnn_expr_ReduceSumMutable(VARP_t input_variable, VARP_t axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceMeanMutable(VARP_t input_variable, VARP_t axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceMaxMutable(VARP_t input_variable, VARP_t axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceMinMutable(VARP_t input_variable, VARP_t axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceProdMutable(VARP_t input_variable, VARP_t axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceAnyMutable(VARP_t input_variable, VARP_t axis, bool keepDims); +MNN_C_API VARP_t mnn_expr_ReduceAllMutable(VARP_t input_variable, VARP_t axis, bool keepDims); + +// EltwiseOPs +MNN_C_API VARP_t mnn_expr_Prod(VARP_t a, VARP_t b, float *coeff, size_t coeffSize); +MNN_C_API VARP_t mnn_expr_Sum(VARP_t a, VARP_t b, float *coeff, size_t coeffSize); +MNN_C_API VARP_t mnn_expr_Max(VARP_t a, VARP_t b, float *coeff, size_t coeffSize); +MNN_C_API VARP_t mnn_expr_Sub(VARP_t a, VARP_t b, float *coeff, size_t coeffSize); +// MNN_PUBLIC VARP _EltwiseProdInt8(VARP x, VARP y, +// std::vector x_weight, std::vector x_bias, std::vector +// x_scale, std::vector x_tensorScale, std::vector y_weight, +// std::vector y_bias, std::vector y_scale, std::vector +// y_tensorScale, std::vector output_weight, std::vector +// output_bias, std::vector output_scale, std::vector +// output_tensorScale); +// MNN_PUBLIC VARP _EltwiseSumInt8(VARP x, VARP y, +// std::vector x_weight, std::vector x_bias, +// std::vector x_scale, std::vector x_tensorScale, +// std::vector y_weight, std::vector y_bias, std::vector +// y_scale, std::vector y_tensorScale, std::vector output_weight, +// std::vector output_bias, std::vector output_scale, +// std::vector output_tensorScale); +// MNN_PUBLIC VARP _EltwiseSubInt8(VARP x, VARP y, +// std::vector x_weight, std::vector x_bias, +// std::vector x_scale, std::vector x_tensorScale, +// std::vector y_weight, std::vector y_bias, std::vector +// y_scale, std::vector y_tensorScale, std::vector output_weight, +// std::vector output_bias, std::vector output_scale, +// std::vector output_tensorScale); +// MNN_PUBLIC VARP _EltwiseMaxInt8(VARP x, VARP y, +// std::vector x_weight, std::vector x_bias, +// std::vector x_scale, std::vector x_tensorScale, +// std::vector y_weight, std::vector y_bias, std::vector +// y_scale, std::vector y_tensorScale, std::vector output_weight, +// std::vector output_bias, std::vector output_scale, +// std::vector output_tensorScale); +MNN_C_API VARP_t mnn_expr_Mod(VARP_t x, VARP_t y); + +// OtherOPs +// template +// VARP _Cast(VARP x) { +// return _Cast(x, halide_type_of()); +// } +MNN_C_API VARP_t mnn_expr_Cast(VARP_t x, halide_type_c_t dtype); +MNN_C_API VARP_t mnn_expr_MatMul(VARP_t a, VARP_t b, bool tranposeA, bool tranposeB); +MNN_C_API VARP_t mnn_expr_Normalize( + VARP_t x, + int32_t acrossSpatial, + int32_t channelShared, + float eps, + const float *scale, + size_t scaleLength +); +MNN_C_API VARP_t mnn_expr_ArgMax(VARP_t input, int axis); +MNN_C_API VARP_t mnn_expr_ArgMin(VARP_t input, int axis); +MNN_C_API VARP_t mnn_expr_BatchMatMul(VARP_t x, VARP_t y, bool adj_x, bool adj_y); +MNN_C_API VARP_t mnn_expr_UnravelIndex(VARP_t indices, VARP_t dims); +MNN_C_API VARP_t mnn_expr_ScatterNd(VARP_t indices, VARP_t updates, VARP_t shape); +MNN_C_API VARP_t mnn_expr_ScatterNd_1(VARP_t indices, VARP_t updates, VARP_t shape, VARP_t input); +MNN_C_API VARP_t mnn_expr_ScatterNd_2(VARP_t indices, VARP_t updates, VARP_t shape, int reduction); +MNN_C_API VARP_t +mnn_expr_ScatterNd_3(VARP_t indices, VARP_t updates, VARP_t shape, VARP_t input, int reduction); +MNN_C_API VARP_t +mnn_expr_ScatterElements(VARP_t data, VARP_t indices, VARP_t updates, int reduction); +MNN_C_API VARP_t +mnn_expr_ScatterElements_1(VARP_t data, VARP_t indices, VARP_t updates, VARP_t axis, int reduction); +MNN_C_API VARP_t +mnn_expr_OneHot(VARP_t indices, VARP_t depth, VARP_t onValue, VARP_t offValue, int axis); +MNN_C_API VARP_t mnn_expr_BroadcastTo(VARP_t a, VARP_t shape); +MNN_C_API VARP_t mnn_expr_LinSpace(VARP_t start, VARP_t stop, VARP_t num); + +MNN_C_API VARP_t mnn_expr_RandomUniform( + VARP_t shape, halide_type_c_t dtype, float low, float high, int seed0, int seed1 +); +MNN_C_API VARP_t mnn_expr_CumSum(VARP_t x, int axis, bool exclusive, bool reverse); +MNN_C_API VARP_t mnn_expr_CumProd(VARP_t x, int axis); +MNN_C_API VecVARP_t mnn_expr_Svd(VARP_t x); +MNN_C_API VARP_t mnn_expr_Histogram(VARP_t x, int bin, int min, int max, int channel); + +// Neural Network Ops +MNN_C_API VARP_t +mnn_expr_Input(const int *shape, size_t shapeLength, int data_format, halide_type_c_t dtype); +MNN_C_API VARP_t mnn_expr_Clone(VARP_t source, bool deepCopy); +MNN_C_API VARP_t mnn_expr_Scalar(const void *ptr, halide_type_c_t type); + +MNN_C_API VARP_t +mnn_expr_Const(void *value, const int *shape, size_t shapeLength, int format, halide_type_c_t type); +// MNN_PUBLIC VARP _InnerProduct(std::vector&& weight, std::vector&& bias, VARP x, +// INTS outputShape); +MNN_C_API VARP_t mnn_expr_Conv( + VARP_t weight, + VARP_t bias, + VARP_t x, + int pad, + const int *stride, + size_t strideLength, + const int *dilate, + size_t dilateLength, + int group, + const int *pads, + size_t padsLength +); +MNN_C_API VARP_t mnn_expr_Deconv( + VARP_t weight, + VARP_t bias, + VARP_t x, + int pad, + const int *stride, + size_t strideLength, + const int *dilate, + size_t dilateLength, + int group, + const int *pads, + size_t padsLength +); +MNN_C_API VARP_t mnn_expr_MaxPool( + VARP_t x, + const int *kernel, + size_t kernelLength, + const int *stride, + size_t strideLength, + int pad, + const int *pads, + size_t padsLength +); +MNN_C_API VARP_t mnn_expr_AvePool( + VARP_t x, + const int *kernel, + size_t kernelLength, + const int *stride, + size_t strideLength, + int pad, + const int *pads, + size_t padsLength +); +MNN_C_API VARP_t +mnn_expr_Reshape(VARP_t x, const int *shape, size_t shapeLength, int original_format); +MNN_C_API VARP_t mnn_expr_Reshape_1(VARP_t x, VARP_t shape); +MNN_C_API VARP_t mnn_expr_Scale( + VARP_t x, int channels, float *scales, size_t scaleLength, float *bias, size_t biasLength +); + +MNN_C_API VARP_t mnn_expr_Relu(VARP_t x, float slope); +MNN_C_API VARP_t mnn_expr_Relu6(VARP_t x, float minValue, float maxValue); +MNN_C_API VARP_t mnn_expr_PRelu(VARP_t x, float *slopes, size_t slopeLength); +MNN_C_API VARP_t mnn_expr_Softmax(VARP_t logits, int axis); +MNN_C_API VARP_t mnn_expr_Softplus(VARP_t features); +MNN_C_API VARP_t mnn_expr_Softsign(VARP_t features); +MNN_C_API VecVARP_t +mnn_expr_Split(VARP_t value, const int *size_splits, size_t size_splitsLength, int axis); +MNN_C_API VARP_t mnn_expr_Slice(VARP_t x, VARP_t starts, VARP_t sizes); +MNN_C_API VARP_t mnn_expr_StridedSlice( + VARP_t input, + VARP_t begin, + VARP_t end, + VARP_t strided, + int32_t beginMask, + int32_t endMask, + int32_t ellipsisMask, + int32_t newAxisMask, + int32_t shrinkAxisMask +); +MNN_C_API VARP_t mnn_expr_StridedSliceWrite( + VARP_t input, + VARP_t begin, + VARP_t end, + VARP_t strided, + VARP_t write, + int32_t beginMask, + int32_t endMask, + int32_t ellipsisMask, + int32_t newAxisMask, + int32_t shrinkAxisMask +); +MNN_C_API VARP_t mnn_expr_Concat(VecVARP_t values, int axis); +MNN_C_API VARP_t mnn_expr_Convert(VARP_t input, int format); +MNN_C_API VARP_t mnn_expr_Transpose(VARP_t x, const int *perm, size_t permLength); +MNN_C_API VARP_t mnn_expr_Transpose_1(VARP_t x, VARP_t perm); +MNN_C_API VARP_t mnn_expr_ChannelShuffle(VARP_t x, int group); +MNN_C_API VARP_t mnn_expr_ChangeInputFormat(VARP_t input, int format); +MNN_C_API VARP_t mnn_expr_Reverse(VARP_t x, VARP_t axis); +MNN_C_API VARP_t mnn_expr_ReverseSequence(VARP_t x, VARP_t y, int batchDim, int seqDim); +MNN_C_API VARP_t +mnn_expr_Crop(VARP_t images, VARP_t size, int axis, const int *offset, size_t offsetLength); +MNN_C_API VARP_t mnn_expr_Resize(VARP_t images, float xScale, float yScale); +MNN_C_API VARP_t mnn_expr_Pad(VARP_t x, VARP_t paddings, int mode); +MNN_C_API VARP_t mnn_expr_ExpandDims(VARP_t input, int axis); +MNN_C_API VARP_t mnn_expr_ExpandDims_1(VARP_t input, VARP_t axis); + +MNN_C_API VARP_t mnn_expr_Shape(VARP_t input, bool nchw); +MNN_C_API VARP_t mnn_expr_Stack(VecVARP_t values, int axis); +// enum InterpolationMethod {BILINEAR, NEAREST}; +MNN_C_API VARP_t mnn_expr_CropAndResize( + VARP_t image, + VARP_t boxes, + VARP_t box_ind, + VARP_t crop_size, + int method, + float extrapolation_value +); +MNN_C_API VARP_t mnn_expr_Fill(VARP_t dims, VARP_t value); +MNN_C_API VARP_t mnn_expr_Tile(VARP_t input, VARP_t multiples); +MNN_C_API VARP_t mnn_expr_Gather(VARP_t params, VARP_t indices); +MNN_C_API VARP_t mnn_expr_GatherV2(VARP_t params, VARP_t indices, VARP_t axis); +MNN_C_API VARP_t mnn_expr_Squeeze(VARP_t input, const int *axis, size_t axisLength); +MNN_C_API VARP_t mnn_expr_Unsqueeze(VARP_t input, const int *axis, size_t axisLength); +MNN_C_API VARP_t mnn_expr_BatchToSpaceND(VARP_t input, VARP_t block_shape, VARP_t crops); +MNN_C_API VARP_t mnn_expr_GatherND(VARP_t params, VARP_t indices); +MNN_C_API VARP_t mnn_expr_GatherElements(VARP_t params, VARP_t indices); +MNN_C_API VARP_t mnn_expr_GatherElements_1(VARP_t params, VARP_t indices, VARP_t axis); +MNN_C_API VARP_t mnn_expr_Selu(VARP_t features, float scale, float alpha); +MNN_C_API VARP_t mnn_expr_Size(VARP_t input); +MNN_C_API VARP_t mnn_expr_Elu(VARP_t features, float alpha); +MNN_C_API VARP_t mnn_expr_Threshold(VARP_t features, float alpha); +MNN_C_API VARP_t mnn_expr_MatrixBandPart(VARP_t input, VARP_t num_lower, VARP_t num_upper); +MNN_C_API VecVARP_t +mnn_expr_Moments(VARP_t x, const int *axis, size_t axisLength, VARP_t shift, bool keepDims); +MNN_C_API VARP_t mnn_expr_SetDiff1D(VARP_t x, VARP_t y); +MNN_C_API VARP_t mnn_expr_SpaceToDepth(VARP_t input, int block_size); +MNN_C_API VARP_t mnn_expr_SpaceToBatchND(VARP_t input, VARP_t block_shape, VARP_t paddings); +MNN_C_API VARP_t mnn_expr_ZerosLike(VARP_t input); +MNN_C_API VecVARP_t mnn_expr_Unstack(VARP_t value, int axis); +MNN_C_API VARP_t mnn_expr_Rank(VARP_t input); +MNN_C_API VARP_t mnn_expr_Range(VARP_t start, VARP_t limit, VARP_t delta); +MNN_C_API VARP_t mnn_expr_DepthToSpace(VARP_t input, int block_size); +// MNN_PUBLIC VARP _PriorBox(VARP feature, VARP image, +// std::vector min_size, std::vector max_size, +// std::vectoraspect_ratio, bool flip, bool clip, +// std::vectorvariance, unsigned int img_h, unsigned int img_w, +// float step_h, float step_w, float offset = 0.5); +MNN_C_API VARP_t mnn_expr_Permute(VARP_t input, const int *dims, size_t dimsLength); +// MNN_PUBLIC VARP _DetectionOutput(VARP location, VARP confidence, VARP priorbox, +// unsigned int num_classes, bool share_location, int background_label_id, +// float nms_threshhold, int nms_topk, int code_type, +// bool variance_encoded_in_target, +// int keep_top_k, float confidence_threshold, float visualize_threshold); +// MNN_PUBLIC std::vector _DetectionPostProcess(VARP encode_boxes, VARP class_predictions, +// VARP anchors, +// int num_classes, int max_detections, +// int max_class_per_detection, int detections_per_class, +// float nms_threshold, float iou_threshold, +// bool use_regular_nms, std::vector centersize_encoding); +MNN_C_API VARP_t mnn_expr_Interp( + VecVARP_t xs, + float widthScale, + float heightScale, + int outputWidth, + int outputHeight, + int resizeType, + bool alignCorners +); +MNN_C_API VARP_t mnn_expr_ZeroGrad(VARP_t x); + +// Int8 Inference +// MNN_PUBLIC VARP _Conv(std::vector&& weight, std::vector&& bias, std::vector&& +// scale, VARP x, INTS channel, INTS kernelSize, +// PaddingMode pad, INTS stride, INTS dilate, int group, INTS pads, bool relu, +// int nbits = 8); +// MNN_PUBLIC VARP _Conv(std::vector&& weight, std::vector&& bias, std::vector&& +// scale, +// VARP x, INTS channel, INTS kernelSize, +// PaddingMode pad, INTS stride, INTS dilate, int group, INTS pads, bool relu, +// int8_t inputZeroPoint, int8_t outputZeroPoint, +// int8_t minValue, int8_t maxValue, bool accumulateToInt16); +// MNN_PUBLIC VARP _Conv(std::vector&& weight, std::vector&& bias, +// std::vector&& weightScale, +// VARP x, INTS channel, INTS kernelSize, +// PaddingMode pad, INTS stride, INTS dilate, int group, INTS pads, bool relu, +// float scaleIn, float scaleOut, +// int8_t inputZeroPoint, int8_t outputZeroPoint, +// int8_t minValue, int8_t maxValue, float weightClampValue, bool +// accumulateToInt16); +MNN_C_API VARP_t mnn_expr_CosineSimilarity(VARP_t input0, VARP_t input1, VARP_t inputDim); +// enum GridSamplePaddingMode {GRID_SAMPLE_PADDING_ZEROS, GRID_SAMPLE_PADDING_BORDER, +// GRID_SAMPLE_PADDING_REFLECTION}; +MNN_C_API VARP_t +mnn_expr_GridSample(VARP_t input, VARP_t grid, int mode, int paddingMode, bool alignCorners); +MNN_C_API VARP_t mnn_expr_FloatToInt8(VARP_t x, VARP_t scale, char minValue, char maxValue); +MNN_C_API VARP_t +mnn_expr_FloatToInt8_1(VARP_t x, VARP_t scale, int8_t minValue, int8_t maxValue, int8_t zeroPoint); +MNN_C_API VARP_t mnn_expr_Int8ToFloat(VARP_t x, VARP_t scale); +MNN_C_API VARP_t mnn_expr_Int8ToFloat_1(VARP_t x, VARP_t scale, int8_t zeroPoint); + +MNN_C_API VARP_t mnn_expr_Select(VARP_t select, VARP_t input0, VARP_t input1); +MNN_C_API VecVARP_t mnn_expr_TopKV2(VARP_t input0, VARP_t input1); +// MNN_PUBLIC VARP _ImageProcess(VARP input, CV::ImageProcess::Config config, CV::Matrix matrix, int +// oh, int ow, int oc, int dtype, uint8_t padVal = 0); mnn_expr_VARP_t +// mnn_expr_ImageProcess(mnn_expr_VARP_t input, CV::ImageProcess::Config config, CV::Matrix matrix, +// int oh, int ow, int oc, int dtype, uint8_t padVal); +MNN_C_API VARP_t mnn_expr_Where(VARP_t x); +MNN_C_API VARP_t mnn_expr_Sort(VARP_t x, int axis, bool arg, bool descend); +MNN_C_API VARP_t mnn_expr_Raster( + VecVARP_t vars, const int *regions, size_t regionsLength, const int *shape, size_t shapeLength +); +MNN_C_API VARP_t mnn_expr_RasterRaw( + VecVARP_t vars, + const int *region, + size_t regionLength, + const int *shape, + size_t shapeLength, + struct halide_type_t dataType, + int format +); + +MNN_C_API VARP_t mnn_expr_Nms( + VARP_t boxes, VARP_t scores, int maxDetections, float iouThreshold, float scoreThreshold +); +MNN_C_API VARP_t mnn_expr_Im2Col( + VARP_t x, + const int *kernelSize, + size_t kernelSizeLength, + const int *dilate, + size_t dilateLength, + const int *pads, + size_t padsLength, + const int *stride, + size_t strideLength +); +MNN_C_API VARP_t mnn_expr_Col2Im( + VARP_t x, + VARP_t outputShape, + const int *kernelSize, + size_t kernelSizeLength, + const int *dilate, + size_t dilateLength, + const int *pads, + size_t padsLength, + const int *stride, + size_t strideLength +); + +#ifdef __cplusplus +} +#endif + +#endif // MNN_EXPR_OP_H diff --git a/src/stdvec.cpp b/src/stdvec.cpp new file mode 100644 index 0000000..4822bbc --- /dev/null +++ b/src/stdvec.cpp @@ -0,0 +1,70 @@ +// +// Created by rainy on 2024/12/16. +// + +#include "stdvec.h" + +#include +#include +#include +#include + +CVD_STD_VEC_FUNC_IMPL(VecU8, uint8_t); +CVD_STD_VEC_FUNC_IMPL(VecI8, int8_t); +CVD_STD_VEC_FUNC_IMPL(VecU16, uint16_t); +CVD_STD_VEC_FUNC_IMPL(VecI16, int16_t); +CVD_STD_VEC_FUNC_IMPL(VecU32, uint32_t); +CVD_STD_VEC_FUNC_IMPL(VecI32, int32_t); +CVD_STD_VEC_FUNC_IMPL(VecU64, uint64_t); +CVD_STD_VEC_FUNC_IMPL(VecI64, int64_t); +CVD_STD_VEC_FUNC_IMPL(VecF32, float_t); +CVD_STD_VEC_FUNC_IMPL(VecF64, double_t); +CVD_STD_VEC_FUNC_IMPL(VecF16, uint16_t); + +// CVD_STD_VEC_FUNC_IMPL_COMMON(VecVecChar) +// VecVecChar* std_VecVecChar_new(size_t length) { +// return new VecVecChar{new std::vector>(length)}; +// } +// +// VecVecChar* std_VecVecChar_new_1(size_t length, VecChar* val) { +// const auto v = static_cast*>(val); +// return new VecVecChar{new std::vector>(length, *v)}; +// } +// +// VecVecChar* std_VecVecChar_new_2(VecVecChar* val_ptr) { +// const auto v = static_cast>*>(val_ptr); +// return new VecVecChar{new std::vector>(*v)}; +// } +// +// VecVecChar* std_VecVecChar_new_3(char** val, VecI32 sizes) { +// if (!sizes.ptr || sizes.ptr->empty()) { +// return new VecVecChar{new std::vector>()}; +// } +// auto rv = new std::vector>(sizes.ptr->size()); +// for (size_t i = 0; i < sizes.ptr->size(); i++) { +// auto t = std::vector(val[i], val[i] + sizes.ptr->at(i)); +// rv->push_back(t); +// } +// return new VecVecChar{rv}; +// } +// +// void std_VecVecChar_push_back(VecVecChar self, VecChar val) { +// const auto v = static_cast*>(val.ptr); +// self->push_back(*v); +// } +// +// VecChar* std_VecVecChar_get(VecVecChar self, int index) { +// return new VecChar{new std::vector(self->at(index))}; +// } +// +// void std_VecVecChar_set(VecVecChar self, int index, VecChar* val) { +// self->at(index) = *(val); +// } +// +// VecChar* std_VecVecChar_data(VecVecChar self) { +// return new VecChar{self->data()}; +// } +// +// VecVecChar* std_VecVecChar_clone(VecVecChar self) { +// return new VecVecChar{new std::vector>(*self)}; +// } diff --git a/src/stdvec.h b/src/stdvec.h new file mode 100644 index 0000000..063e666 --- /dev/null +++ b/src/stdvec.h @@ -0,0 +1,112 @@ +// +// Created by rainy on 2024/12/16. +// + +#ifndef STDVEC_H +#define STDVEC_H + +#include +#include +#include + +#ifdef __cplusplus +#include +extern "C" { + +#define CVD_STD_VEC_FUNC_IMPL(TYPE, ELEM) \ + CVD_STD_VEC_FUNC_IMPL_COMMON(TYPE); \ + TYPE std_##TYPE##_new(size_t length) { return new std::vector(length); } \ + TYPE std_##TYPE##_new_1(size_t length, ELEM val) { return new std::vector(length, val); } \ + TYPE std_##TYPE##_new_2(size_t length, ELEM *val_ptr) { \ + return new std::vector(val_ptr, val_ptr + length); \ + } \ + void std_##TYPE##_push_back(TYPE self, ELEM val) { self->push_back(val); } \ + ELEM std_##TYPE##_get(TYPE self, size_t index) { return self->at(index); } \ + void std_##TYPE##_set(TYPE self, size_t index, ELEM val) { self->at(index) = val; } \ + ELEM *std_##TYPE##_data(TYPE self) { return self->data(); } \ + TYPE std_##TYPE##_clone(TYPE self) { return new std::vector(*(self)); } + +#define CVD_STD_VEC_FUNC_IMPL_COMMON(TYPE) \ + void std_##TYPE##_free(TYPE self) { delete self; } \ + size_t std_##TYPE##_length(TYPE self) { return self->size(); } \ + void std_##TYPE##_resize(TYPE self, size_t new_len) { self->resize(new_len); } \ + void std_##TYPE##_reserve(TYPE self, size_t new_len) { self->reserve(new_len); } \ + void std_##TYPE##_clear(TYPE self) { self->clear(); } \ + void std_##TYPE##_shrink_to_fit(TYPE self) { self->shrink_to_fit(); } \ + void std_##TYPE##_extend(TYPE self, TYPE other) { \ + self->insert(self->end(), other->begin(), other->end()); \ + } +#endif + +#define CVD_STD_VEC_FUNC_DEF(TYPE, ELEM) \ + TYPE std_##TYPE##_new(size_t length); \ + TYPE std_##TYPE##_new_1(size_t length, ELEM val); \ + TYPE std_##TYPE##_new_2(size_t length, ELEM *val_ptr); \ + void std_##TYPE##_free(TYPE self); \ + void std_##TYPE##_push_back(TYPE self, ELEM val); \ + ELEM std_##TYPE##_get(TYPE self, size_t index); \ + void std_##TYPE##_set(TYPE self, size_t index, ELEM val); \ + size_t std_##TYPE##_length(TYPE self); \ + ELEM *std_##TYPE##_data(TYPE self); \ + void std_##TYPE##_resize(TYPE self, size_t new_len); \ + void std_##TYPE##_reserve(TYPE self, size_t new_len); \ + void std_##TYPE##_clear(TYPE self); \ + void std_##TYPE##_shrink_to_fit(TYPE self); \ + void std_##TYPE##_extend(TYPE self, TYPE other); \ + TYPE std_##TYPE##_clone(TYPE self) + +#ifdef __cplusplus +#define CVD_TYPEDEF_STD_VEC(TYPE, NAME) typedef std::vector *NAME +#else +#define CVD_TYPEDEF_STD_VEC(TYPE, NAME) typedef void *NAME +#endif + +typedef unsigned char uchar; +CVD_TYPEDEF_STD_VEC(uchar, VecUChar); +CVD_TYPEDEF_STD_VEC(char, VecChar); +CVD_TYPEDEF_STD_VEC(uint8_t, VecU8); +CVD_TYPEDEF_STD_VEC(int8_t, VecI8); +CVD_TYPEDEF_STD_VEC(uint16_t, VecU16); +CVD_TYPEDEF_STD_VEC(int16_t, VecI16); +CVD_TYPEDEF_STD_VEC(uint32_t, VecU32); +CVD_TYPEDEF_STD_VEC(int32_t, VecI32); +CVD_TYPEDEF_STD_VEC(int64_t, VecI64); +CVD_TYPEDEF_STD_VEC(uint64_t, VecU64); +CVD_TYPEDEF_STD_VEC(float_t, VecF32); +CVD_TYPEDEF_STD_VEC(double_t, VecF64); +CVD_TYPEDEF_STD_VEC(uint16_t, VecF16); // TODO: change to native float16 + +CVD_STD_VEC_FUNC_DEF(VecU8, uint8_t); +CVD_STD_VEC_FUNC_DEF(VecI8, int8_t); +CVD_STD_VEC_FUNC_DEF(VecU16, uint16_t); +CVD_STD_VEC_FUNC_DEF(VecI16, int16_t); +CVD_STD_VEC_FUNC_DEF(VecU32, uint32_t); +CVD_STD_VEC_FUNC_DEF(VecI32, int32_t); +CVD_STD_VEC_FUNC_DEF(VecU64, uint64_t); +CVD_STD_VEC_FUNC_DEF(VecI64, int64_t); +CVD_STD_VEC_FUNC_DEF(VecF32, float_t); +CVD_STD_VEC_FUNC_DEF(VecF64, double_t); +CVD_STD_VEC_FUNC_DEF(VecF16, uint16_t); + +// CVD_STD_VEC_FUNC_DEF(VecVecChar, VecChar); +// VecVecChar* std_VecVecChar_new(size_t length); +// VecVecChar* std_VecVecChar_new_1(size_t length, VecChar* val); +// VecVecChar* std_VecVecChar_new_2(VecVecChar* val_ptr); +// VecVecChar* std_VecVecChar_new_3(char** val, VecI32 sizes); +// void std_VecVecChar_free(VecVecChar* self); +// size_t std_VecVecChar_length(VecVecChar* self); +// void std_VecVecChar_push_back(VecVecChar* self, VecChar val); +// VecChar* std_VecVecChar_get(VecVecChar* self, int index); +// void std_VecVecChar_set(VecVecChar* self, int index, VecChar* val); +// VecChar* std_VecVecChar_data(VecVecChar* self); +// void std_VecVecChar_reserve(VecVecChar* self, size_t size); +// void std_VecVecChar_resize(VecVecChar* self, size_t size); +// void std_VecVecChar_clear(VecVecChar* self); +// void std_VecVecChar_shrink_to_fit(VecVecChar* self); +// VecVecChar* std_VecVecChar_clone(VecVecChar* self); + +#ifdef __cplusplus +} +#endif + +#endif // STDVEC_H diff --git a/src/test/test_interpreter.cpp b/src/test/test_interpreter.cpp index edc4cf6..2931482 100644 --- a/src/test/test_interpreter.cpp +++ b/src/test/test_interpreter.cpp @@ -7,6 +7,8 @@ #include "../interpreter.h" #include "MNN/ImageProcess.hpp" #include "MNN/Matrix.h" +#include "MNN/expr/Expr.hpp" +#include "expr.h" #include #include #include @@ -18,6 +20,16 @@ int main(int argc, char *argv[]) { return 1; } + // auto varp = MNN::Express::Variable::load(argv[1]); + auto varp = mnn_expr_VARP_static_load(argv[1]); + mnn_expr_VARP_static_save(varp, "model.bin"); + auto _info = mnn_expr_VARP_getInfo(&varp->at(0)); + + if (_info == nullptr) { + std::cout << "getInfo.info is nullptr" << std::endl; + return 1; + } + // 创建interpreter实例 mnn_interpreter_t interpreter = mnn_interpreter_create_from_file(argv[1], nullptr); if (!interpreter) { diff --git a/test/expr/VARP_test.dart b/test/expr/VARP_test.dart new file mode 100644 index 0000000..8dba666 --- /dev/null +++ b/test/expr/VARP_test.dart @@ -0,0 +1,6 @@ +import 'package:mnn/mnn.dart' as mnn; +import 'package:test/test.dart'; + +void main() { + +} diff --git a/test/expr/variable_test.dart b/test/expr/variable_test.dart new file mode 100644 index 0000000..9023748 --- /dev/null +++ b/test/expr/variable_test.dart @@ -0,0 +1,144 @@ +import 'dart:ffi'; +import 'dart:io'; + +import 'package:mnn/mnn.dart' as mnn; +import 'package:test/test.dart'; + +void main() { + test('VariableInfo', () { + final shape = [2, 1, 640, 640]; + final info = mnn.VariableInfo.create( + order: mnn.DimensionFormat.NCHW, + dim: shape, + type: mnn.HalideType.f64, + ); + info.syncSize(); + expect(info.order, mnn.DimensionFormat.NCHW); + expect(info.dim, shape); + expect(info.ndim, shape.length); + expect(info.type, mnn.HalideType.f64); + expect(info.size, shape.reduce((a, b) => a * b)); + expect(info.toString(), startsWith('VariableInfo(')); + + info.dispose(); + }); + + test('Expr', () { + final shape = [2, 1, 640, 640]; + final info = mnn.VariableInfo.create( + order: mnn.DimensionFormat.NCHW, + dim: shape, + type: mnn.HalideType.f64, + ); + final expr = mnn.Expr.fromVariableInfo(info, mnn.InputType.CONSTANT); + + // info will be copied internally, so we can dispose it after use + info.dispose(); + + expr.name = "testExpr"; + expect(expr.name, "testExpr"); + expect(expr.outputSize, 1); + expect(expr.requireInfo, true); + expect(expr.inputType, mnn.InputType.CONSTANT); + expect(expr.outputName(0), ""); + expect(expr.outputInfo(0), isA()); + + final tensor = mnn.Tensor.create(); + final expr1 = mnn.Expr.fromTensor(tensor); + expr1.name = "exprFromTensor"; + expect(expr1.name, "exprFromTensor"); + + mnn.Expr.replace(expr, expr1); + expect(expr.name, expr1.name); + + expect(expr1.toString(), startsWith('Expr(')); + expect(expr1.toString(), contains('name=exprFromTensor')); + + expr.dispose(); + expr1.dispose(); + }); + + test('VARP', () { + final info = mnn.VariableInfo.create( + order: mnn.DimensionFormat.NHWC, + dim: [], + type: mnn.HalideType.f64, + ); + final expr = mnn.Expr.fromVariableInfo(info, mnn.InputType.CONSTANT); + final varp = mnn.VARP.create(expr, index: 0); + expect(varp.getName(), isEmpty); + varp.setName("testVariable"); + expect(varp.getName(), "testVariable"); + + final info1 = varp.getInfo(); + expect(info1.order, mnn.DimensionFormat.NHWC); + expect(info1.dim, []); + expect(info1.type, mnn.HalideType.f64); + expect(info1.size, 1); // ceil + info1.dispose(); + + varp.resize([1, 2, 3, 3]); + final info2 = varp.getInfo(); + expect(info2.order, mnn.DimensionFormat.NHWC); + expect(info2.dim, [1, 2, 3, 3]); + expect(info2.type, mnn.HalideType.f64); + expect(info2.size, 1 * 2 * 3 * 3); + info2.dispose(); + + final (expr1, index) = varp.expr; + expect(expr1.name, "testVariable"); + expect(index, 0); + expr1.dispose(); + + final varp1 = mnn.VARP.list([1, 2, 3, 4], format: mnn.DimensionFormat.NCHW); + varp.input(varp1); + varp1.dispose(); + + final info3 = varp.getInfo(); + expect(info3.order, mnn.DimensionFormat.NCHW); + expect(info3.dim, [4]); + expect(info3.type, mnn.HalideType.i32); + expect(info3.size, 4); + info3.dispose(); + + final pRead = varp.readMap(); + expect(pRead.asTypedList(4), [1, 2, 3, 4]); + varp.unMap(); + + expect(varp.linkNumber(), isA()); + + final tensor = varp.getTensor(); + expect(tensor.shape, [4]); + + varp.setExpr(expr, 1); + expect(varp.expr.$1, isA()); + expect(varp.expr.$2, 1); + + expect(varp.toString(), startsWith('VARP(')); + + varp.dispose(); + }); + + test('Variable load save', () { + final outFile = File('test/tmp/variable_save.mnn'); + if (!outFile.parent.existsSync()) { + outFile.parent.createSync(recursive: true); + } + final varp = mnn.VARP.list([1, 2, 3, 4], format: mnn.DimensionFormat.NCHW); + print(varp.getInfo()); + + mnn.VARP.saveToFile([varp], outFile.path); + + final buf = outFile.readAsBytesSync(); + final bufOut = mnn.VARP.saveToBuffer([varp]); + expect(bufOut.data, buf); + + final varpLoaded = mnn.VARP.loadFromBuffer(bufOut.data); + final varpLoadedFile = mnn.VARP.loadFromFile(outFile.path); + expect(varpLoaded[0].data, varp.data); + expect(varpLoadedFile[0].data, varp.data); + + // final varpMap = mnn.VARP.loadMapFromFile("test/data/mnist-8.mnn"); + // print(varpMap["Plus214_Output_0"]?.data); + }); +} diff --git a/test/interpreter_test.dart b/test/interpreter_test.dart index 906a4cb..d52c2c0 100644 --- a/test/interpreter_test.dart +++ b/test/interpreter_test.dart @@ -25,21 +25,21 @@ void testSession(mnn.Session session) { final input = session.getInput(); expect(input, isNotNull); expect(input?.shape, [1, 1, 28, 28]); - expect(input?.type, mnn.HalideType.f32()); + expect(input?.type, mnn.HalideType.f32); final output = session.getOutput(); expect(output, isNotNull); expect(output?.shape, [1, 10]); - expect(output?.type, mnn.HalideType.f32()); + expect(output?.type, mnn.HalideType.f32); } { final input = session.getInput(name: "Input3"); expect(input, isNotNull); expect(input?.shape, [1, 1, 28, 28]); - expect(input?.type, mnn.HalideType.f32()); + expect(input?.type, mnn.HalideType.f32); final output = session.getOutput(name: "Plus214_Output_0"); expect(output, isNotNull); expect(output?.shape, [1, 10]); - expect(output?.type, mnn.HalideType.f32()); + expect(output?.type, mnn.HalideType.f32); } final inputs = session.getInputAll(); @@ -69,7 +69,7 @@ Future testInferenceMnistCopy( final inputTensor = mnn.Tensor.fromData( input.shape, - mnn.HalideType.f32(), + mnn.HalideType.f32, data: pixData.buffer.asUint8List(), dimType: mnn.DimensionType.MNN_CAFFE, ); @@ -87,7 +87,7 @@ Future testInferenceMnistCopy( final outputTensor = mnn.Tensor.fromTensor(output!, dimType: mnn.DimensionType.MNN_CAFFE); expect(output.copyToHost(outputTensor), true); expect(outputTensor.shape, [1, 10]); - expect(outputTensor.type, mnn.HalideType.f32()); + expect(outputTensor.type, mnn.HalideType.f32); final logits = outputTensor.host.cast().asTypedList(10); expect(logits.indexOf(logits.reduce(max)), target); } diff --git a/test/tensor_test.dart b/test/tensor_test.dart index 5e43c30..ef9818e 100644 --- a/test/tensor_test.dart +++ b/test/tensor_test.dart @@ -49,7 +49,7 @@ void main() async { final data = Float32List.fromList(List.generate(27, (index) => index.toDouble())); final tensor = mnn.Tensor.fromData( [1, 3, 3, 3], - mnn.HalideType.f32(), + mnn.HalideType.f32, data: data.buffer.asUint8List(), dimType: mnn.DimensionType.MNN_CAFFE, ); @@ -89,11 +89,11 @@ void main() async { test('Tensor.createDevice', () { final tensor = - mnn.Tensor.createDevice([2, 3, 4, 5], mnn.HalideType.f32(), dimType: mnn.DimensionType.MNN_CAFFE); + mnn.Tensor.createDevice([2, 3, 4, 5], mnn.HalideType.f32, dimType: mnn.DimensionType.MNN_CAFFE); expect(tensor.dimensions, 4); expect(tensor.elementSize, tensor.count); expect(tensor.shape, [2, 3, 4, 5]); - expect(tensor.type, mnn.HalideType.f32()); + expect(tensor.type, mnn.HalideType.f32); expect(tensor.dimensionType, mnn.DimensionType.MNN_CAFFE); expect(tensor.deviceId, isA()); }); @@ -108,7 +108,7 @@ void main() async { final tensor = mnn.Tensor.create(); final buffer = tensor.buffer; expect(buffer, isA()); - expect(buffer.type, mnn.HalideType.f32()); // default type is float32 + expect(buffer.type, mnn.HalideType.f32); // default type is float32 expect(buffer.dimensions, 4); expect(buffer.dimensions, tensor.dimensions); });