├── .gitignore
├── README.md
├── app
├── CMakeLists.txt
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── tarmac
│ │ └── yolov2Tiny
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── coco.names
│ │ ├── yolov3-tiny.bin
│ │ └── yolov3-tiny.param
│ ├── cpp
│ │ ├── include
│ │ │ └── ncnn
│ │ │ │ ├── allocator.h
│ │ │ │ ├── benchmark.h
│ │ │ │ ├── blob.h
│ │ │ │ ├── command.h
│ │ │ │ ├── cpu.h
│ │ │ │ ├── datareader.h
│ │ │ │ ├── gpu.h
│ │ │ │ ├── layer.h
│ │ │ │ ├── layer_type.h
│ │ │ │ ├── layer_type_enum.h
│ │ │ │ ├── mat.h
│ │ │ │ ├── modelbin.h
│ │ │ │ ├── net.h
│ │ │ │ ├── opencv.h
│ │ │ │ ├── option.h
│ │ │ │ ├── paramdict.h
│ │ │ │ ├── pipeline.h
│ │ │ │ └── platform.h
│ │ └── yolov3-tiny-jni.cpp
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── yolov3tiny
│ │ │ ├── MainActivity.java
│ │ │ ├── PhotoUtil.java
│ │ │ └── yolov3Tiny.java
│ ├── jniLibs
│ │ └── armeabi-v7a
│ │ │ └── libncnn.a
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── tarmac
│ └── yolov2Tiny
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── screenshot.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.aar
4 | *.ap_
5 | *.aab
6 |
7 | # Files for the ART/Dalvik VM
8 | *.dex
9 |
10 | # Java class files
11 | *.class
12 |
13 | # Generated files
14 | bin/
15 | gen/
16 | out/
17 | # Uncomment the following line in case you need and you don't have the release build type files in your app
18 | # release/
19 |
20 | # Gradle files
21 | .gradle/
22 | build/
23 |
24 | # Local configuration file (sdk path, etc)
25 | local.properties
26 |
27 | # Proguard folder generated by Eclipse
28 | proguard/
29 |
30 | # Log Files
31 | *.log
32 |
33 | # Android Studio Navigation editor temp files
34 | .navigation/
35 |
36 | # Android Studio captures folder
37 | captures/
38 |
39 | # IntelliJ
40 | *.iml
41 | .idea
42 | .idea/workspace.xml
43 | .idea/tasks.xml
44 | .idea/gradle.xml
45 | .idea/assetWizardSettings.xml
46 | .idea/dictionaries
47 | .idea/libraries
48 | # Android Studio 3 in .gitignore file.
49 | .idea/caches
50 | .idea/modules.xml
51 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you
52 | .idea/navEditor.xml
53 |
54 | # Keystore files
55 | # Uncomment the following lines if you do not want to check your keystore files in.
56 | #*.jks
57 | #*.keystore
58 |
59 | # External native build folder generated in Android Studio 2.2 and later
60 | .externalNativeBuild
61 | .cxx/
62 |
63 | # Google Services (e.g. APIs or Firebase)
64 | # google-services.json
65 |
66 | # Freeline
67 | freeline.py
68 | freeline/
69 | freeline_project_description.json
70 |
71 | # fastlane
72 | fastlane/report.xml
73 | fastlane/Preview.html
74 | fastlane/screenshots
75 | fastlane/test_output
76 | fastlane/readme.md
77 |
78 | # Version control
79 | vcs.xml
80 |
81 | # lint
82 | lint/intermediates/
83 | lint/generated/
84 | lint/outputs/
85 | lint/tmp/
86 | # lint/reports/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Android demo to use darknet model in ncnn.
2 |
3 | Steps:
4 |
5 | 1. Use [darknet2ncnn](https://github.com/xiangweizeng/darknet2ncnn) to convert darknet model to ncnn model.
6 | 2. Build [xiangweizeng/ncnn](https://github.com/xiangweizeng/ncnn) for android.
7 | 3. Put model, ncnn header files and static lib into project.
8 |
9 | 
10 |
11 | Reference: https://github.com/chehongshu/ncnnforandroid_objectiondetection_Mobilenetssd
12 |
13 | For vulkan support: https://github.com/nihui/ncnn-android-styletransfer
14 |
15 | You can find another user-friendly tool at: https://github.com/Tencent/ncnn/tree/master/tools/darknet
16 |
--------------------------------------------------------------------------------
/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | # Creates and names a library, sets it as either STATIC
9 | # or SHARED, and provides the relative paths to its source code.
10 | # You can define multiple libraries, and CMake builds them for you.
11 | # Gradle automatically packages shared libraries with your APK.
12 | set(CMAKE_BUILD_TYPE RELEASE)
13 |
14 | include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include/ncnn)
15 |
16 | # openmp
17 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
19 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fopenmp")
20 |
21 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer -fstrict-aliasing -ffast-math")
22 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fomit-frame-pointer -fstrict-aliasing -ffast-math")
23 |
24 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
25 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden")
26 |
27 | # disable rtti and exceptions
28 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
29 |
30 | add_library (libncnn STATIC IMPORTED)
31 | set_target_properties(libncnn PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libncnn.a)
32 |
33 | set(lib_src ${CMAKE_SOURCE_DIR}/src/main/cpp/yolov3-tiny-jni.cpp)
34 |
35 | add_library( # Sets the name of the library.
36 | yolov3_tiny_jni
37 |
38 | # Sets the library as a shared library.
39 | SHARED
40 |
41 | # Provides a relative path to your source file(s).
42 | ${lib_src})
43 |
44 | # Searches for a specified prebuilt library and stores the path as a
45 | # variable. Because CMake includes system libraries in the search path by
46 | # default, you only need to specify the name of the public NDK library
47 | # you want to add. CMake verifies that the library exists before
48 | # completing its build.
49 |
50 | find_library( # Sets the name of the path variable.
51 | log-lib
52 |
53 | # Specifies the name of the NDK library that
54 | # you want CMake to locate.
55 | log
56 | android)
57 | #find_library( # Sets the name of the path variable.
58 | #JniGraphics
59 |
60 | # Specifies the name of the NDK library that
61 | # you want CMake to locate.
62 | #jnigraphics)
63 |
64 | # Specifies libraries CMake should link to your target library. You
65 | # can link multiple libraries, such as libraries you define in this
66 | # build script, prebuilt third-party libraries, or system libraries.
67 |
68 | target_link_libraries( # Specifies the target library.
69 | yolov3_tiny_jni
70 | libncnn
71 | android
72 | jnigraphics
73 | # vulkan
74 | # Links the target library to the log library
75 | # included in the NDK.
76 | ${log-lib})
77 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.example.yolov3Tiny"
7 | minSdkVersion 21
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | externalNativeBuild {
13 | cmake {
14 | cppFlags "-std=c++11 -Ofast -Wno-unused-result -Wfatal-errors -fPIC -fno-rtti -fno-exceptions -fopenmp"
15 | abiFilters "armeabi-v7a"
16 | arguments '-DANDROID_PLATFORM=android-21',
17 | '-DANDROID_ARM_NEON=ON'
18 | }
19 | }
20 | }
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | externalNativeBuild {
28 | cmake {
29 | path "CMakeLists.txt"
30 | }
31 | }
32 | sourceSets {
33 | main {
34 | jniLibs.srcDirs = ["src/main/jniLibs"]
35 | jni.srcDirs = ['src/cpp']
36 | }
37 | }
38 | }
39 |
40 | dependencies {
41 | implementation fileTree(dir: 'libs', include: ['*.jar'])
42 | implementation 'com.android.support:appcompat-v7:28.0.0'
43 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
44 | testImplementation 'junit:junit:4.12'
45 | implementation 'com.github.bumptech.glide:glide:4.3.1'
46 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
47 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
48 | }
49 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/tarmac/yolov2Tiny/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.tarmac.yolov2Tiny;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.tarmac.yolov2_tiny", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/assets/coco.names:
--------------------------------------------------------------------------------
1 | background
2 | person
3 | bicycle
4 | car
5 | motorbike
6 | aeroplane
7 | bus
8 | train
9 | truck
10 | boat
11 | traffic light
12 | fire hydrant
13 | stop sign
14 | parking meter
15 | bench
16 | bird
17 | cat
18 | dog
19 | horse
20 | sheep
21 | cow
22 | elephant
23 | bear
24 | zebra
25 | giraffe
26 | backpack
27 | umbrella
28 | handbag
29 | tie
30 | suitcase
31 | frisbee
32 | skis
33 | snowboard
34 | sports ball
35 | kite
36 | baseball bat
37 | baseball glove
38 | skateboard
39 | surfboard
40 | tennis racket
41 | bottle
42 | wine glass
43 | cup
44 | fork
45 | knife
46 | spoon
47 | bowl
48 | banana
49 | apple
50 | sandwich
51 | orange
52 | broccoli
53 | carrot
54 | hot dog
55 | pizza
56 | donut
57 | cake
58 | chair
59 | sofa
60 | pottedplant
61 | bed
62 | diningtable
63 | toilet
64 | tvmonitor
65 | laptop
66 | mouse
67 | remote
68 | keyboard
69 | cell phone
70 | microwave
71 | oven
72 | toaster
73 | sink
74 | refrigerator
75 | book
76 | clock
77 | vase
78 | scissors
79 | teddy bear
80 | hair drier
81 | toothbrush
82 |
--------------------------------------------------------------------------------
/app/src/main/assets/yolov3-tiny.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/assets/yolov3-tiny.bin
--------------------------------------------------------------------------------
/app/src/main/assets/yolov3-tiny.param:
--------------------------------------------------------------------------------
1 | 7767517
2 | 50 52
3 | Input data 0 1 data 0=416 1=416 2=3
4 | Convolution conv_0 1 1 data conv_0 0=16 1=3 2=1 3=1 4=1 5=0 6=432
5 | BatchNorm conv_0_batch_norm 1 1 conv_0 conv_0_batch_norm 0=16 1=0.00001
6 | ReLU conv_0_activation 1 1 conv_0_batch_norm conv_0_activation 0=0.1
7 | Pooling maxpool_1 1 1 conv_0_activation maxpool_1 0=0 1=2 2=2 3=0 5=1 13=0 14=1 15=1
8 | Convolution conv_2 1 1 maxpool_1 conv_2 0=32 1=3 2=1 3=1 4=1 5=0 6=4608
9 | BatchNorm conv_2_batch_norm 1 1 conv_2 conv_2_batch_norm 0=32 1=0.00001
10 | ReLU conv_2_activation 1 1 conv_2_batch_norm conv_2_activation 0=0.1
11 | Pooling maxpool_3 1 1 conv_2_activation maxpool_3 0=0 1=2 2=2 3=0 5=1 13=0 14=1 15=1
12 | Convolution conv_4 1 1 maxpool_3 conv_4 0=64 1=3 2=1 3=1 4=1 5=0 6=18432
13 | BatchNorm conv_4_batch_norm 1 1 conv_4 conv_4_batch_norm 0=64 1=0.00001
14 | ReLU conv_4_activation 1 1 conv_4_batch_norm conv_4_activation 0=0.1
15 | Pooling maxpool_5 1 1 conv_4_activation maxpool_5 0=0 1=2 2=2 3=0 5=1 13=0 14=1 15=1
16 | Convolution conv_6 1 1 maxpool_5 conv_6 0=128 1=3 2=1 3=1 4=1 5=0 6=73728
17 | BatchNorm conv_6_batch_norm 1 1 conv_6 conv_6_batch_norm 0=128 1=0.00001
18 | ReLU conv_6_activation 1 1 conv_6_batch_norm conv_6_activation 0=0.1
19 | Pooling maxpool_7 1 1 conv_6_activation maxpool_7 0=0 1=2 2=2 3=0 5=1 13=0 14=1 15=1
20 | Convolution conv_8 1 1 maxpool_7 conv_8 0=256 1=3 2=1 3=1 4=1 5=0 6=294912
21 | BatchNorm conv_8_batch_norm 1 1 conv_8 conv_8_batch_norm 0=256 1=0.00001
22 | ReLU conv_8_activation 1 1 conv_8_batch_norm conv_8_activation 0=0.1
23 | Split conv_8_activation_split 1 2 conv_8_activation conv_8_activation_split_0 conv_8_activation_split_1
24 | Pooling maxpool_9 1 1 conv_8_activation_split_0 maxpool_9 0=0 1=2 2=2 3=0 5=1 13=0 14=1 15=1
25 | Convolution conv_10 1 1 maxpool_9 conv_10 0=512 1=3 2=1 3=1 4=1 5=0 6=1179648
26 | BatchNorm conv_10_batch_norm 1 1 conv_10 conv_10_batch_norm 0=512 1=0.00001
27 | ReLU conv_10_activation 1 1 conv_10_batch_norm conv_10_activation 0=0.1
28 | Pooling maxpool_11 1 1 conv_10_activation maxpool_11 0=0 1=2 2=1 3=0 5=1 13=0 14=1 15=1
29 | Convolution conv_12 1 1 maxpool_11 conv_12 0=1024 1=3 2=1 3=1 4=1 5=0 6=4718592
30 | BatchNorm conv_12_batch_norm 1 1 conv_12 conv_12_batch_norm 0=1024 1=0.00001
31 | ReLU conv_12_activation 1 1 conv_12_batch_norm conv_12_activation 0=0.1
32 | Convolution conv_13 1 1 conv_12_activation conv_13 0=256 1=1 2=1 3=1 4=0 5=0 6=262144
33 | BatchNorm conv_13_batch_norm 1 1 conv_13 conv_13_batch_norm 0=256 1=0.00001
34 | ReLU conv_13_activation 1 1 conv_13_batch_norm conv_13_activation 0=0.1
35 | Split conv_13_activation_split 1 2 conv_13_activation conv_13_activation_split_0 conv_13_activation_split_1
36 | Convolution conv_14 1 1 conv_13_activation_split_0 conv_14 0=512 1=3 2=1 3=1 4=1 5=0 6=1179648
37 | BatchNorm conv_14_batch_norm 1 1 conv_14 conv_14_batch_norm 0=512 1=0.00001
38 | ReLU conv_14_activation 1 1 conv_14_batch_norm conv_14_activation 0=0.1
39 | Convolution conv_15 1 1 conv_14_activation conv_15 0=255 1=1 2=1 3=1 4=0 5=1 6=130560
40 | DarknetActivation conv_15_activation 1 1 conv_15 conv_15_activation 0=3
41 | Concat route_17 1 1 conv_13_activation_split_1 route_17 0=0
42 | Convolution conv_18 1 1 route_17 conv_18 0=128 1=1 2=1 3=1 4=0 5=0 6=32768
43 | BatchNorm conv_18_batch_norm 1 1 conv_18 conv_18_batch_norm 0=128 1=0.00001
44 | ReLU conv_18_activation 1 1 conv_18_batch_norm conv_18_activation 0=0.1
45 | Interp upsample_19 1 1 conv_18_activation upsample_19 0=1 1=2.f 2=2.f
46 | Concat route_20 2 1 upsample_19 conv_8_activation_split_1 route_20 0=0
47 | Convolution conv_21 1 1 route_20 conv_21 0=256 1=3 2=1 3=1 4=1 5=0 6=884736
48 | BatchNorm conv_21_batch_norm 1 1 conv_21 conv_21_batch_norm 0=256 1=0.00001
49 | ReLU conv_21_activation 1 1 conv_21_batch_norm conv_21_activation 0=0.1
50 | Convolution conv_22 1 1 conv_21_activation conv_22 0=255 1=1 2=1 3=1 4=0 5=1 6=65280
51 | DarknetActivation conv_22_activation 1 1 conv_22 conv_22_activation 0=3
52 | Yolov3Detection yolo_23 2 1 conv_15_activation conv_22_activation yolo_23 0=80 1=6 2=0 3=0.25f 4=0.45f 5=416 6=416 -23307=12,81.000000,82.000000,135.000000,169.000000,344.000000,319.000000,10.000000,14.000000,23.000000,27.000000,37.000000,58.000000
53 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/allocator.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_ALLOCATOR_H
16 | #define NCNN_ALLOCATOR_H
17 |
18 | #ifdef _WIN32
19 | #define WIN32_LEAN_AND_MEAN
20 | #include
21 | #else
22 | #include
23 | #endif
24 |
25 | #include
26 | #include
27 | #include
28 | #include "platform.h"
29 |
30 | #if NCNN_VULKAN
31 | #include
32 | #include "gpu.h"
33 | #endif // NCNN_VULKAN
34 |
35 | namespace ncnn {
36 |
37 | // the alignment of all the allocated buffers
38 | #define MALLOC_ALIGN 16
39 |
40 | // Aligns a pointer to the specified number of bytes
41 | // ptr Aligned pointer
42 | // n Alignment size that must be a power of two
43 | template static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
44 | {
45 | return (_Tp*)(((size_t)ptr + n-1) & -n);
46 | }
47 |
48 | // Aligns a buffer size to the specified number of bytes
49 | // The function returns the minimum number that is greater or equal to sz and is divisible by n
50 | // sz Buffer size to align
51 | // n Alignment size that must be a power of two
52 | static inline size_t alignSize(size_t sz, int n)
53 | {
54 | return (sz + n-1) & -n;
55 | }
56 |
57 | static inline void* fastMalloc(size_t size)
58 | {
59 | #if _MSC_VER
60 | return _aligned_malloc(size, MALLOC_ALIGN);
61 | #elif _POSIX_C_SOURCE >= 200112L || (__ANDROID__ && __ANDROID_API__ >= 17)
62 | void* ptr = 0;
63 | if (posix_memalign(&ptr, MALLOC_ALIGN, size))
64 | ptr = 0;
65 | return ptr;
66 | #elif __ANDROID__ && __ANDROID_API__ < 17
67 | return memalign(MALLOC_ALIGN, size);
68 | #else
69 | unsigned char* udata = (unsigned char*)malloc(size + sizeof(void*) + MALLOC_ALIGN);
70 | if (!udata)
71 | return 0;
72 | unsigned char** adata = alignPtr((unsigned char**)udata + 1, MALLOC_ALIGN);
73 | adata[-1] = udata;
74 | return adata;
75 | #endif
76 | }
77 |
78 | static inline void fastFree(void* ptr)
79 | {
80 | if (ptr)
81 | {
82 | #if _MSC_VER
83 | _aligned_free(ptr);
84 | #elif _POSIX_C_SOURCE >= 200112L || (__ANDROID__ && __ANDROID_API__ >= 17)
85 | free(ptr);
86 | #elif __ANDROID__ && __ANDROID_API__ < 17
87 | free(ptr);
88 | #else
89 | unsigned char* udata = ((unsigned char**)ptr)[-1];
90 | free(udata);
91 | #endif
92 | }
93 | }
94 |
95 | // exchange-add operation for atomic operations on reference counters
96 | #if defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32)
97 | // atomic increment on the linux version of the Intel(tm) compiler
98 | # define NCNN_XADD(addr, delta) (int)_InterlockedExchangeAdd(const_cast(reinterpret_cast(addr)), delta)
99 | #elif defined __GNUC__
100 | # if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__)
101 | # ifdef __ATOMIC_ACQ_REL
102 | # define NCNN_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), delta, __ATOMIC_ACQ_REL)
103 | # else
104 | # define NCNN_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), delta, 4)
105 | # endif
106 | # else
107 | # if defined __ATOMIC_ACQ_REL && !defined __clang__
108 | // version for gcc >= 4.7
109 | # define NCNN_XADD(addr, delta) (int)__atomic_fetch_add((unsigned*)(addr), (unsigned)(delta), __ATOMIC_ACQ_REL)
110 | # else
111 | # define NCNN_XADD(addr, delta) (int)__sync_fetch_and_add((unsigned*)(addr), (unsigned)(delta))
112 | # endif
113 | # endif
114 | #elif defined _MSC_VER && !defined RC_INVOKED
115 | # include
116 | # define NCNN_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta)
117 | #else
118 | // thread-unsafe branch
119 | static inline int NCNN_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; }
120 | #endif
121 |
122 | class Allocator
123 | {
124 | public:
125 | virtual ~Allocator();
126 | virtual void* fastMalloc(size_t size) = 0;
127 | virtual void fastFree(void* ptr) = 0;
128 | };
129 |
130 | class PoolAllocator : public Allocator
131 | {
132 | public:
133 | PoolAllocator();
134 | ~PoolAllocator();
135 |
136 | // ratio range 0 ~ 1
137 | // default cr = 0.75
138 | void set_size_compare_ratio(float scr);
139 |
140 | // release all budgets immediately
141 | void clear();
142 |
143 | virtual void* fastMalloc(size_t size);
144 | virtual void fastFree(void* ptr);
145 |
146 | private:
147 | Mutex budgets_lock;
148 | Mutex payouts_lock;
149 | unsigned int size_compare_ratio;// 0~256
150 | std::list< std::pair > budgets;
151 | std::list< std::pair > payouts;
152 | };
153 |
154 | class UnlockedPoolAllocator : public Allocator
155 | {
156 | public:
157 | UnlockedPoolAllocator();
158 | ~UnlockedPoolAllocator();
159 |
160 | // ratio range 0 ~ 1
161 | // default cr = 0.75
162 | void set_size_compare_ratio(float scr);
163 |
164 | // release all budgets immediately
165 | void clear();
166 |
167 | virtual void* fastMalloc(size_t size);
168 | virtual void fastFree(void* ptr);
169 |
170 | private:
171 | unsigned int size_compare_ratio;// 0~256
172 | std::list< std::pair > budgets;
173 | std::list< std::pair > payouts;
174 | };
175 |
176 | #if NCNN_VULKAN
177 |
178 | class VkBufferMemory
179 | {
180 | public:
181 | VkBuffer buffer;
182 |
183 | // the base offset assigned by allocator
184 | size_t offset;
185 | size_t capacity;
186 |
187 | VkDeviceMemory memory;
188 | void* mapped_ptr;
189 |
190 | // buffer state, modified by command functions internally
191 | // 0=null
192 | // 1=created
193 | // 2=transfer
194 | // 3=compute
195 | // 4=readonly
196 | mutable int state;
197 |
198 | // initialize and modified by mat
199 | int refcount;
200 | };
201 |
202 | class VkAllocator
203 | {
204 | public:
205 | VkAllocator(const VulkanDevice* _vkdev);
206 | virtual ~VkAllocator() { clear(); }
207 | virtual void clear() {}
208 | virtual VkBufferMemory* fastMalloc(size_t size) = 0;
209 | virtual void fastFree(VkBufferMemory* ptr) = 0;
210 |
211 | public:
212 | const VulkanDevice* vkdev;
213 | uint32_t memory_type_index;
214 | bool mappable;
215 |
216 | protected:
217 | VkBuffer create_buffer(size_t size, VkBufferUsageFlags usage);
218 | VkDeviceMemory allocate_memory(size_t size);
219 | VkDeviceMemory allocate_dedicated_memory(size_t size, VkBuffer buffer);
220 | };
221 |
222 | class VkBlobBufferAllocator : public VkAllocator
223 | {
224 | public:
225 | VkBlobBufferAllocator(const VulkanDevice* vkdev);
226 | virtual ~VkBlobBufferAllocator();
227 |
228 | public:
229 | // release all budgets immediately
230 | virtual void clear();
231 |
232 | virtual VkBufferMemory* fastMalloc(size_t size);
233 | virtual void fastFree(VkBufferMemory* ptr);
234 |
235 | private:
236 | size_t block_size;
237 | size_t buffer_offset_alignment;
238 | std::vector< std::list< std::pair > > budgets;
239 | std::vector buffer_blocks;
240 | };
241 |
242 | class VkWeightBufferAllocator : public VkAllocator
243 | {
244 | public:
245 | VkWeightBufferAllocator(const VulkanDevice* vkdev);
246 | virtual ~VkWeightBufferAllocator();
247 |
248 | public:
249 | // release all blocks immediately
250 | virtual void clear();
251 |
252 | public:
253 | virtual VkBufferMemory* fastMalloc(size_t size);
254 | virtual void fastFree(VkBufferMemory* ptr);
255 |
256 | private:
257 | size_t block_size;
258 | size_t buffer_offset_alignment;
259 | std::vector buffer_block_free_spaces;
260 | std::vector buffer_blocks;
261 | std::vector dedicated_buffer_blocks;
262 | };
263 |
264 | class VkStagingBufferAllocator : public VkAllocator
265 | {
266 | public:
267 | VkStagingBufferAllocator(const VulkanDevice* vkdev);
268 | virtual ~VkStagingBufferAllocator();
269 |
270 | public:
271 | // ratio range 0 ~ 1
272 | // default cr = 0.75
273 | void set_size_compare_ratio(float scr);
274 |
275 | // release all budgets immediately
276 | virtual void clear();
277 |
278 | virtual VkBufferMemory* fastMalloc(size_t size);
279 | virtual void fastFree(VkBufferMemory* ptr);
280 |
281 | private:
282 | unsigned int size_compare_ratio;// 0~256
283 | std::list budgets;
284 | };
285 |
286 | class VkWeightStagingBufferAllocator : public VkAllocator
287 | {
288 | public:
289 | VkWeightStagingBufferAllocator(const VulkanDevice* vkdev);
290 | virtual ~VkWeightStagingBufferAllocator();
291 |
292 | public:
293 | virtual VkBufferMemory* fastMalloc(size_t size);
294 | virtual void fastFree(VkBufferMemory* ptr);
295 |
296 | private:
297 | };
298 |
299 | #endif // NCNN_VULKAN
300 |
301 | } // namespace ncnn
302 |
303 | #endif // NCNN_ALLOCATOR_H
304 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/benchmark.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_BENCHMARK_H
16 | #define NCNN_BENCHMARK_H
17 |
18 | #include "platform.h"
19 | #include "mat.h"
20 | #include "layer.h"
21 |
22 | namespace ncnn {
23 |
24 | // get now timestamp in ms
25 | double get_current_time();
26 |
27 | #if NCNN_BENCHMARK
28 |
29 | void benchmark(const Layer* layer, double start, double end);
30 | void benchmark(const Layer* layer, const Mat& bottom_blob, Mat& top_blob, double start, double end);
31 |
32 | #endif // NCNN_BENCHMARK
33 |
34 | } // namespace ncnn
35 |
36 | #endif // NCNN_BENCHMARK_H
37 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/blob.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_BLOB_H
16 | #define NCNN_BLOB_H
17 |
18 | #include
19 | #include
20 | #include "platform.h"
21 |
22 | namespace ncnn {
23 |
24 | class Blob
25 | {
26 | public:
27 | // empty
28 | Blob();
29 |
30 | public:
31 | #if NCNN_STRING
32 | // blob name
33 | std::string name;
34 | #endif // NCNN_STRING
35 | // layer index which produce this blob as output
36 | int producer;
37 | // layer index which need this blob as input
38 | std::vector consumers;
39 | };
40 |
41 | } // namespace ncnn
42 |
43 | #endif // NCNN_BLOB_H
44 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/command.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_COMMAND_H
16 | #define NCNN_COMMAND_H
17 |
18 | #include "platform.h"
19 |
20 | #if NCNN_VULKAN
21 |
22 | #include
23 | #include
24 | #include "mat.h"
25 | #include "pipeline.h"
26 |
27 | namespace ncnn {
28 |
29 | class Command
30 | {
31 | public:
32 | Command(const VulkanDevice* vkdev, uint32_t queue_family_index);
33 | virtual ~Command();
34 |
35 | protected:
36 | int create_command_pool();
37 | int create_command_buffer();
38 |
39 | // record issue
40 | int begin_command_buffer();
41 | int end_command_buffer();
42 | int queue_submit_and_wait_fence();
43 |
44 | protected:
45 | const VulkanDevice* vkdev;
46 | uint32_t queue_family_index;
47 |
48 | VkCommandPool command_pool;
49 | VkCommandBuffer command_buffer;
50 |
51 | VkFence fence;
52 | };
53 |
54 | class VkCompute : public Command
55 | {
56 | public:
57 | VkCompute(const VulkanDevice* vkdev);
58 | ~VkCompute();
59 |
60 | void record_upload(const VkMat& m);
61 |
62 | void record_download(const VkMat& m);
63 |
64 | void record_clone(const VkMat& src, const VkMat& dst);
65 |
66 | void record_copy_region(const VkMat& src, const VkMat& dst, const VkBufferCopy& region);
67 |
68 | void record_copy_regions(const VkMat& src, const VkMat& dst, const std::vector& regions);
69 |
70 | void record_pipeline(const Pipeline* pipeline, const std::vector& bindings, const std::vector& constants, const VkMat& m);
71 |
72 | void record_write_timestamp(uint32_t query);
73 |
74 | #if __ANDROID_API__ >= 26
75 | void record_import_android_hardware_buffer(const ImportAndroidHardwareBufferPipeline* pipeline, VkImage image, VkImageView imageView, const VkMat& m);
76 | #endif // __ANDROID_API__ >= 26
77 |
78 | int submit_and_wait();
79 |
80 | int reset();
81 |
82 | #if NCNN_BENCHMARK
83 | int create_query_pool(uint32_t query_count);
84 |
85 | int get_query_pool_results(uint32_t first_query, uint32_t query_count, std::vector& results);
86 | #endif // NCNN_BENCHMARK
87 |
88 | protected:
89 | // record pipeline things
90 | void record_bind_pipeline(VkPipeline pipeline);
91 | void record_update_bindings(VkPipelineLayout pipeline_layout, VkDescriptorSetLayout descriptorset_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, const std::vector& bindings);
92 | void record_push_constants(VkPipelineLayout pipeline_layout, const std::vector& constants);
93 | void record_dispatch(const uint32_t* group_count_xyz);
94 |
95 | // record barrier things
96 | void record_transfer_compute_barrier(const VkMat& m);
97 | void record_compute_transfer_barrier(const VkMat& m);
98 | void record_compute_compute_barrier(const VkMat& m);
99 | void record_transfer_transfer_barrier(const VkMat& m);
100 |
101 | // record prepare things
102 | void record_prepare_transfer_barrier(const VkMat& m);
103 | void record_prepare_compute_barrier(const VkMat& m);
104 |
105 | void record_initial_image_compute_barrier(VkImage image);
106 |
107 | #if __ANDROID_API__ >= 26
108 | void record_update_import_android_hardware_buffer_bindings(VkPipelineLayout pipeline_layout, VkDescriptorSetLayout descriptorset_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, VkSampler sampler, VkImageView imageView, const VkMat& m);
109 | #endif // __ANDROID_API__ >= 26
110 |
111 | #if NCNN_BENCHMARK
112 | void reset_query_pool();
113 | #endif // NCNN_BENCHMARK
114 |
115 | protected:
116 | // recording issue
117 | void copy_buffer(VkBuffer src, size_t src_offset, VkBuffer dst, size_t dst_offset, size_t size);
118 | void copy_buffer_regions(VkBuffer src, VkBuffer dst, const std::vector& regions);
119 | void bind_pipeline(VkPipeline pipeline);
120 | void bind_descriptorset(VkPipelineLayout pipeline_layout, VkDescriptorSet descriptorset);
121 | void update_bindings(VkPipelineLayout pipeline_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, const std::vector& descriptorBufferInfos);
122 | void push_constants(VkPipelineLayout pipeline_layout, const std::vector& constants);
123 | void dispatch(const uint32_t* group_count_xyz);
124 | void transfer_compute_barrier(VkBuffer buffer, size_t offset, size_t size);
125 | void compute_transfer_barrier(VkBuffer buffer, size_t offset, size_t size);
126 | void compute_compute_barrier(VkBuffer buffer, size_t offset, size_t size);
127 | void transfer_transfer_barrier(VkBuffer buffer, size_t offset, size_t size);
128 | void initial_image_compute_barrier(VkImage image);
129 | #if __ANDROID_API__ >= 26
130 | void update_import_android_hardware_buffer_bindings(VkPipelineLayout pipeline_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, const VkDescriptorImageInfo& descriptorImageInfo, const VkDescriptorBufferInfo& descriptorBufferInfo);
131 | #endif // __ANDROID_API__ >= 26
132 | #if NCNN_BENCHMARK
133 | void write_timestamp(uint32_t query);
134 | #endif // NCNN_BENCHMARK
135 |
136 | protected:
137 | // delayed record
138 | // the good-old path for device without VK_KHR_push_descriptor
139 | std::vector descriptor_pools;
140 | std::vector descriptorsets;
141 | struct record_type
142 | {
143 | // 0=copy
144 | // 1=copy regions
145 | // 2=bind pipeline
146 | // 3=bind descriptorset
147 | // 4=push constants
148 | // 5=dispatch
149 | // 6=transfer-compute barrier
150 | // 7=compute-transfer barrier
151 | // 8=compute-compute barrier
152 | // 9=transfer-transfer barrier
153 | // 10=write timestamp
154 | // 11=initial image compute barrier
155 | int type;
156 |
157 | union
158 | {
159 | struct { VkBuffer src; size_t src_offset; VkBuffer dst; size_t dst_offset; size_t size; } copy;
160 | struct { VkBuffer src; VkBuffer dst; } copy_regions;
161 | struct { VkPipeline pipeline; } bind_pipeline;
162 | struct { VkPipelineLayout pipeline_layout; VkDescriptorSet descriptorset; } bind_descriptorset;
163 | struct { VkPipelineLayout pipeline_layout; } push_constants;
164 | struct { uint32_t group_count_xyz[3]; } dispatch;
165 | struct { VkBuffer buffer; size_t offset; size_t size; } transfer_compute_barrier;
166 | struct { VkBuffer buffer; size_t offset; size_t size; } compute_transfer_barrier;
167 | struct { VkBuffer buffer; size_t offset; size_t size; } compute_compute_barrier;
168 | struct { VkBuffer buffer; size_t offset; size_t size; } transfer_transfer_barrier;
169 | #if NCNN_BENCHMARK
170 | struct { uint32_t query; } write_timestamp;
171 | #endif // NCNN_BENCHMARK
172 | struct { VkImage image; } initial_image_compute_barrier;
173 | };
174 |
175 | std::vector regions;
176 | std::vector constants;
177 | };
178 | std::vector delayed_records;
179 |
180 | #if NCNN_BENCHMARK
181 | uint32_t query_count;
182 | VkQueryPool query_pool;
183 | #endif // NCNN_BENCHMARK
184 | };
185 |
186 | class VkTransfer : public Command
187 | {
188 | public:
189 | VkTransfer(const VulkanDevice* vkdev);
190 | ~VkTransfer();
191 |
192 | void record_upload(const Mat& src, VkMat& dst, const Option& opt);
193 |
194 | int submit_and_wait();
195 |
196 | public:
197 | VkAllocator* weight_vkallocator;
198 | VkAllocator* staging_vkallocator;
199 |
200 | protected:
201 | // recording issue
202 | void copy_buffer(VkBuffer src, size_t src_offset, VkBuffer dst, size_t dst_offset, size_t size);
203 | void copy_buffer_regions(VkBuffer src, VkBuffer dst, const std::vector& regions);
204 |
205 | protected:
206 | size_t buffer_offset_alignment;
207 | VkBufferMemory* staging_data;
208 |
209 | // delayed record
210 | struct record_type
211 | {
212 | size_t size;
213 | Mat mat;
214 | VkMat vkmat;
215 | };
216 | std::vector delayed_records;
217 | };
218 |
219 | } // namespace ncnn
220 |
221 | #endif // NCNN_VULKAN
222 |
223 | #endif // NCNN_COMMAND_H
224 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/cpu.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_CPU_H
16 | #define NCNN_CPU_H
17 |
18 | namespace ncnn {
19 |
20 | // test optional cpu features
21 | // neon = armv7 neon or aarch64 asimd
22 | int cpu_support_arm_neon();
23 | // vfpv4 = armv7 fp16 + fma
24 | int cpu_support_arm_vfpv4();
25 | // asimdhp = aarch64 asimd half precision
26 | int cpu_support_arm_asimdhp();
27 |
28 | // cpu info
29 | int get_cpu_count();
30 |
31 | // bind all threads on little clusters if powersave enabled
32 | // affacts HMP arch cpu like ARM big.LITTLE
33 | // only implemented on android at the moment
34 | // switching powersave is expensive and not thread-safe
35 | // 0 = all cores enabled(default)
36 | // 1 = only little clusters enabled
37 | // 2 = only big clusters enabled
38 | // return 0 if success for setter function
39 | int get_cpu_powersave();
40 | int set_cpu_powersave(int powersave);
41 |
42 | // misc function wrapper for openmp routines
43 | int get_omp_num_threads();
44 | void set_omp_num_threads(int num_threads);
45 |
46 | int get_omp_dynamic();
47 | void set_omp_dynamic(int dynamic);
48 |
49 | } // namespace ncnn
50 |
51 | #endif // NCNN_CPU_H
52 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/datareader.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_DATAREADER_H
16 | #define NCNN_DATAREADER_H
17 |
18 | #include
19 | #include "platform.h"
20 |
21 | #if __ANDROID_API__ >= 9
22 | #include
23 | #endif
24 |
25 | namespace ncnn {
26 |
27 | // data read wrapper
28 | class DataReader
29 | {
30 | public:
31 | virtual ~DataReader();
32 |
33 | #if NCNN_STRING
34 | // parse plain param text
35 | // return 1 if scan success
36 | virtual int scan(const char* format, void* p) const;
37 | #endif // NCNN_STRING
38 |
39 | // read binary param and model data
40 | // return bytes read
41 | virtual int read(void* buf, int size) const;
42 | };
43 |
44 | #if NCNN_STDIO
45 | class DataReaderFromStdio : public DataReader
46 | {
47 | public:
48 | DataReaderFromStdio(FILE* fp);
49 |
50 | #if NCNN_STRING
51 | virtual int scan(const char* format, void* p) const;
52 | #endif // NCNN_STRING
53 | virtual int read(void* buf, int size) const;
54 |
55 | protected:
56 | FILE* fp;
57 | };
58 | #endif // NCNN_STDIO
59 |
60 | class DataReaderFromMemory : public DataReader
61 | {
62 | public:
63 | DataReaderFromMemory(const unsigned char*& mem);
64 |
65 | #if NCNN_STRING
66 | virtual int scan(const char* format, void* p) const;
67 | #endif // NCNN_STRING
68 | virtual int read(void* buf, int size) const;
69 |
70 | protected:
71 | const unsigned char*& mem;
72 | };
73 |
74 | #if __ANDROID_API__ >= 9
75 | class DataReaderFromAndroidAsset : public DataReader
76 | {
77 | public:
78 | DataReaderFromAndroidAsset(AAsset* asset);
79 |
80 | #if NCNN_STRING
81 | virtual int scan(const char* format, void* p) const;
82 | #endif // NCNN_STRING
83 | virtual int read(void* buf, int size) const;
84 |
85 | protected:
86 | AAsset* asset;
87 | mutable const unsigned char* mem;
88 | };
89 | #endif // __ANDROID_API__ >= 9
90 |
91 | } // namespace ncnn
92 |
93 | #endif // NCNN_DATAREADER_H
94 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/gpu.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_GPU_H
16 | #define NCNN_GPU_H
17 |
18 | #include "platform.h"
19 |
20 | #if NCNN_VULKAN
21 |
22 | #include
23 | #include
24 |
25 | namespace ncnn {
26 |
27 | // instance
28 | int create_gpu_instance();
29 | void destroy_gpu_instance();
30 |
31 | // instance extension capability
32 | extern int support_VK_KHR_external_memory_capabilities;
33 | extern int support_VK_KHR_get_physical_device_properties2;
34 | extern int support_VK_KHR_get_surface_capabilities2;
35 | extern int support_VK_KHR_surface;
36 | extern int support_VK_EXT_debug_utils;
37 | #if __ANDROID_API__ >= 26
38 | extern int support_VK_KHR_android_surface;
39 | #endif // __ANDROID_API__ >= 26
40 |
41 | // VK_KHR_external_memory_capabilities
42 | extern PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR vkGetPhysicalDeviceExternalBufferPropertiesKHR;
43 |
44 | // VK_KHR_get_physical_device_properties2
45 | extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
46 | extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
47 | extern PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR;
48 | extern PFN_vkGetPhysicalDeviceImageFormatProperties2KHR vkGetPhysicalDeviceImageFormatProperties2KHR;
49 | extern PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR;
50 | extern PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR;
51 | extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR vkGetPhysicalDeviceSparseImageFormatProperties2KHR;
52 |
53 | // VK_KHR_get_surface_capabilities2
54 | extern PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR;
55 | extern PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR;
56 |
57 | // VK_KHR_surface
58 | extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
59 | extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
60 | extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
61 | extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
62 | extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
63 |
64 | #if __ANDROID_API__ >= 26
65 | // VK_KHR_android_surface
66 | extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
67 | #endif // __ANDROID_API__ >= 26
68 |
69 | // get info
70 | int get_gpu_count();
71 | int get_default_gpu_index();
72 |
73 | class GpuInfo
74 | {
75 | public:
76 | // vulkan physical device
77 | VkPhysicalDevice physical_device;
78 |
79 | // memory properties
80 | VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;
81 |
82 | // info
83 | uint32_t api_version;
84 | uint32_t driver_version;
85 | uint32_t vendor_id;
86 | uint32_t device_id;
87 | uint8_t pipeline_cache_uuid[VK_UUID_SIZE];
88 |
89 | // 0 = discrete gpu
90 | // 1 = integrated gpu
91 | // 2 = virtual gpu
92 | // 3 = cpu
93 | int type;
94 |
95 | // hardware capability
96 | uint32_t max_shared_memory_size;
97 | uint32_t max_workgroup_count[3];
98 | uint32_t max_workgroup_invocations;
99 | uint32_t max_workgroup_size[3];
100 | size_t memory_map_alignment;
101 | size_t buffer_offset_alignment;
102 | float timestamp_period;
103 |
104 | // runtime
105 | uint32_t compute_queue_family_index;
106 | uint32_t graphics_queue_family_index;
107 | uint32_t transfer_queue_family_index;
108 |
109 | uint32_t compute_queue_count;
110 | uint32_t graphics_queue_count;
111 | uint32_t transfer_queue_count;
112 |
113 | // fp16 and int8 feature
114 | bool support_fp16_packed;
115 | bool support_fp16_storage;
116 | bool support_fp16_arithmetic;
117 | bool support_int8_storage;
118 | bool support_int8_arithmetic;
119 |
120 | // ycbcr conversion feature
121 | bool support_ycbcr_conversion;
122 |
123 | // extension capability
124 | int support_VK_KHR_8bit_storage;
125 | int support_VK_KHR_16bit_storage;
126 | int support_VK_KHR_bind_memory2;
127 | int support_VK_KHR_dedicated_allocation;
128 | int support_VK_KHR_descriptor_update_template;
129 | int support_VK_KHR_external_memory;
130 | int support_VK_KHR_get_memory_requirements2;
131 | int support_VK_KHR_maintenance1;
132 | int support_VK_KHR_push_descriptor;
133 | int support_VK_KHR_sampler_ycbcr_conversion;
134 | int support_VK_KHR_shader_float16_int8;
135 | int support_VK_KHR_shader_float_controls;
136 | int support_VK_KHR_storage_buffer_storage_class;
137 | int support_VK_KHR_swapchain;
138 | int support_VK_EXT_queue_family_foreign;
139 | #if __ANDROID_API__ >= 26
140 | int support_VK_ANDROID_external_memory_android_hardware_buffer;
141 | #endif // __ANDROID_API__ >= 26
142 | };
143 |
144 | const GpuInfo& get_gpu_info(int device_index = get_default_gpu_index());
145 |
146 | class VkAllocator;
147 | class VulkanDevice
148 | {
149 | public:
150 | VulkanDevice(int device_index = get_default_gpu_index());
151 | ~VulkanDevice();
152 |
153 | const GpuInfo& info;
154 |
155 | VkDevice vkdevice() const { return device; }
156 |
157 | VkShaderModule get_shader_module(const char* name) const;
158 |
159 | VkShaderModule compile_shader_module(const uint32_t* spv_data, size_t spv_data_size) const;
160 |
161 | uint32_t find_memory_index(uint32_t memory_type_bits, VkFlags required, VkFlags preferred, VkFlags preferred_not) const;
162 | bool is_mappable(uint32_t memory_type_index) const;
163 |
164 | VkQueue acquire_queue(uint32_t queue_family_index) const;
165 | void reclaim_queue(uint32_t queue_family_index, VkQueue queue) const;
166 |
167 | // allocator on this device
168 | VkAllocator* acquire_blob_allocator() const;
169 | void reclaim_blob_allocator(VkAllocator* allocator) const;
170 |
171 | VkAllocator* acquire_staging_allocator() const;
172 | void reclaim_staging_allocator(VkAllocator* allocator) const;
173 |
174 | // VK_KHR_bind_memory2
175 | PFN_vkBindBufferMemory2KHR vkBindBufferMemory2KHR;
176 | PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR;
177 |
178 | // VK_KHR_descriptor_update_template
179 | PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR;
180 | PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR;
181 | PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR;
182 |
183 | // VK_KHR_get_memory_requirements2
184 | PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;
185 | PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
186 | PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR;
187 |
188 | // VK_KHR_maintenance1
189 | PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR;
190 |
191 | // VK_KHR_push_descriptor
192 | PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR;
193 | PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
194 |
195 | // VK_KHR_sampler_ycbcr_conversion
196 | PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR;
197 | PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR;
198 |
199 | // VK_KHR_swapchain
200 | PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
201 | PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
202 | PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
203 | PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
204 | PFN_vkQueuePresentKHR vkQueuePresentKHR;
205 |
206 | #if __ANDROID_API__ >= 26
207 | // VK_ANDROID_external_memory_android_hardware_buffer
208 | PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID;
209 | PFN_vkGetMemoryAndroidHardwareBufferANDROID vkGetMemoryAndroidHardwareBufferANDROID;
210 | #endif // __ANDROID_API__ >= 26
211 |
212 | protected:
213 | // shader management
214 | int create_shader_module();
215 | void destroy_shader_module();
216 |
217 | // device extension
218 | int init_device_extension();
219 |
220 | private:
221 | VkDevice device;
222 | std::vector shader_modules;
223 |
224 | // hardware queue
225 | mutable std::vector compute_queues;
226 | mutable std::vector graphics_queues;
227 | mutable std::vector transfer_queues;
228 | mutable Mutex queue_lock;
229 |
230 | // default blob allocator for each queue
231 | mutable std::vector blob_allocators;
232 | mutable Mutex blob_allocator_lock;
233 |
234 | // default staging allocator for each queue
235 | mutable std::vector staging_allocators;
236 | mutable Mutex staging_allocator_lock;
237 | };
238 |
239 | VulkanDevice* get_gpu_device(int device_index = get_default_gpu_index());
240 |
241 | } // namespace ncnn
242 |
243 | #endif // NCNN_VULKAN
244 |
245 | #endif // NCNN_GPU_H
246 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/layer.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_LAYER_H
16 | #define NCNN_LAYER_H
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include "platform.h"
23 | #include "mat.h"
24 | #include "modelbin.h"
25 | #include "option.h"
26 | #include "paramdict.h"
27 |
28 | #if NCNN_VULKAN
29 | #include
30 | #include "command.h"
31 | #include "pipeline.h"
32 | #endif // NCNN_VULKAN
33 |
34 | namespace ncnn {
35 |
36 | class Layer
37 | {
38 | public:
39 | // empty
40 | Layer();
41 | // virtual destructor
42 | virtual ~Layer();
43 |
44 | // load layer specific parameter from parsed dict
45 | // return 0 if success
46 | virtual int load_param(const ParamDict& pd);
47 |
48 | // load layer specific weight data from model binary
49 | // return 0 if success
50 | virtual int load_model(const ModelBin& mb);
51 |
52 | // layer implementation specific setup
53 | // return 0 if success
54 | virtual int create_pipeline(const Option& opt);
55 |
56 | // layer implementation specific clean
57 | // return 0 if success
58 | virtual int destroy_pipeline(const Option& opt);
59 |
60 | public:
61 | // one input and one output blob
62 | bool one_blob_only;
63 |
64 | // support inplace inference
65 | bool support_inplace;
66 |
67 | // support vulkan compute
68 | bool support_vulkan;
69 |
70 | // accept input blob with packed storage
71 | bool support_packing;
72 |
73 | public:
74 | // implement inference
75 | // return 0 if success
76 | virtual int forward(const std::vector& bottom_blobs, std::vector& top_blobs, const Option& opt) const;
77 | virtual int forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const;
78 |
79 | // implement inplace inference
80 | // return 0 if success
81 | virtual int forward_inplace(std::vector& bottom_top_blobs, const Option& opt) const;
82 | virtual int forward_inplace(Mat& bottom_top_blob, const Option& opt) const;
83 |
84 | #if NCNN_VULKAN
85 | public:
86 | // upload weight blob from host to device
87 | virtual int upload_model(VkTransfer& cmd, const Option& opt);
88 |
89 | public:
90 | // implement inference
91 | // return 0 if success
92 | virtual int forward(const std::vector& bottom_blobs, std::vector& top_blobs, VkCompute& cmd, const Option& opt) const;
93 | virtual int forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const;
94 |
95 | // implement inplace inference
96 | // return 0 if success
97 | virtual int forward_inplace(std::vector& bottom_top_blobs, VkCompute& cmd, const Option& opt) const;
98 | virtual int forward_inplace(VkMat& bottom_top_blob, VkCompute& cmd, const Option& opt) const;
99 |
100 | public:
101 | // assigned immediately after creating this layer
102 | const VulkanDevice* vkdev;
103 | #endif // NCNN_VULKAN
104 |
105 | public:
106 | // layer type index
107 | int typeindex;
108 | #if NCNN_STRING
109 | // layer type name
110 | std::string type;
111 | // layer name
112 | std::string name;
113 | #endif // NCNN_STRING
114 | // blob index which this layer needs as input
115 | std::vector bottoms;
116 | // blob index which this layer produces as output
117 | std::vector tops;
118 | };
119 |
120 | // layer factory function
121 | typedef Layer* (*layer_creator_func)();
122 |
123 | struct layer_registry_entry
124 | {
125 | #if NCNN_STRING
126 | // layer type name
127 | const char* name;
128 | #endif // NCNN_STRING
129 | // layer factory entry
130 | layer_creator_func creator;
131 | };
132 |
133 | #if NCNN_STRING
134 | // get layer type from type name
135 | int layer_to_index(const char* type);
136 | // create layer from type name
137 | Layer* create_layer(const char* type);
138 | #endif // NCNN_STRING
139 | // create layer from layer type
140 | Layer* create_layer(int index);
141 |
142 | #define DEFINE_LAYER_CREATOR(name) \
143 | ::ncnn::Layer* name##_layer_creator() { return new name; }
144 |
145 | } // namespace ncnn
146 |
147 | #endif // NCNN_LAYER_H
148 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/layer_type.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_LAYER_TYPE_H
16 | #define NCNN_LAYER_TYPE_H
17 |
18 | namespace ncnn {
19 |
20 | namespace LayerType {
21 | enum
22 | {
23 | #include "layer_type_enum.h"
24 | CustomBit = (1<<8),
25 | };
26 | } // namespace LayerType
27 |
28 | } // namespace ncnn
29 |
30 | #endif // NCNN_LAYER_TYPE_H
31 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/layer_type_enum.h:
--------------------------------------------------------------------------------
1 | // Layer Type Enum header
2 | //
3 | // This file is auto-generated by cmake, don't edit it.
4 |
5 | AbsVal = 0,
6 | ArgMax = 1,
7 | BatchNorm = 2,
8 | Bias = 3,
9 | BNLL = 4,
10 | Concat = 5,
11 | Convolution = 6,
12 | Crop = 7,
13 | Deconvolution = 8,
14 | Dropout = 9,
15 | Eltwise = 10,
16 | ELU = 11,
17 | Embed = 12,
18 | Exp = 13,
19 | Flatten = 14,
20 | InnerProduct = 15,
21 | Input = 16,
22 | Log = 17,
23 | LRN = 18,
24 | MemoryData = 19,
25 | MVN = 20,
26 | Pooling = 21,
27 | Power = 22,
28 | PReLU = 23,
29 | Proposal = 24,
30 | Reduction = 25,
31 | ReLU = 26,
32 | Reshape = 27,
33 | ROIPooling = 28,
34 | Scale = 29,
35 | Sigmoid = 30,
36 | Slice = 31,
37 | Softmax = 32,
38 | Split = 33,
39 | SPP = 34,
40 | TanH = 35,
41 | Threshold = 36,
42 | Tile = 37,
43 | RNN = 38,
44 | LSTM = 39,
45 | BinaryOp = 40,
46 | UnaryOp = 41,
47 | ConvolutionDepthWise = 42,
48 | Padding = 43,
49 | Squeeze = 44,
50 | ExpandDims = 45,
51 | Normalize = 46,
52 | Permute = 47,
53 | PriorBox = 48,
54 | DetectionOutput = 49,
55 | Interp = 50,
56 | DeconvolutionDepthWise = 51,
57 | ShuffleChannel = 52,
58 | InstanceNorm = 53,
59 | Clip = 54,
60 | Reorg = 55,
61 | YoloDetectionOutput = 56,
62 | Quantize = 57,
63 | Dequantize = 58,
64 | Yolov3DetectionOutput = 59,
65 | PSROIPooling = 60,
66 | ROIAlign = 61,
67 | Packing = 62,
68 | Requantize = 63,
69 | Cast = 64,
70 | HardSigmoid = 65,
71 | SELU = 66,
72 | HardSwish = 67,
73 | Noop = 68,
74 | DarknetActivation = 69,
75 | DarknetShortcut = 70,
76 | Yolov1Detection = 71,
77 | Yolov3Detection = 72,
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/mat.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_MAT_H
16 | #define NCNN_MAT_H
17 |
18 | #include
19 | #include
20 | #include
21 | #if __ARM_NEON
22 | #include
23 | #endif
24 | #include "platform.h"
25 | #include "allocator.h"
26 | #include "option.h"
27 | #include "gpu.h"
28 |
29 | #if NCNN_VULKAN
30 | #include
31 | #endif // NCNN_VULKAN
32 |
33 | #if NCNN_PIXEL
34 | #if __ANDROID_API__ >= 9
35 | #include
36 | #include
37 | #endif // __ANDROID_API__ >= 9
38 | #endif // NCNN_PIXEL
39 |
40 | namespace ncnn {
41 |
42 | #if NCNN_VULKAN
43 | class VkMat;
44 | #endif // NCNN_VULKAN
45 |
46 | // the three dimension matrix
47 | class Mat
48 | {
49 | public:
50 | // empty
51 | Mat();
52 | // vec
53 | Mat(int w, size_t elemsize = 4u, Allocator* allocator = 0);
54 | // image
55 | Mat(int w, int h, size_t elemsize = 4u, Allocator* allocator = 0);
56 | // dim
57 | Mat(int w, int h, int c, size_t elemsize = 4u, Allocator* allocator = 0);
58 | // packed vec
59 | Mat(int w, size_t elemsize, int elempack, Allocator* allocator = 0);
60 | // packed image
61 | Mat(int w, int h, size_t elemsize, int elempack, Allocator* allocator = 0);
62 | // packed dim
63 | Mat(int w, int h, int c, size_t elemsize, int elempack, Allocator* allocator = 0);
64 | // copy
65 | Mat(const Mat& m);
66 | // external vec
67 | Mat(int w, void* data, size_t elemsize = 4u, Allocator* allocator = 0);
68 | // external image
69 | Mat(int w, int h, void* data, size_t elemsize = 4u, Allocator* allocator = 0);
70 | // external dim
71 | Mat(int w, int h, int c, void* data, size_t elemsize = 4u, Allocator* allocator = 0);
72 | // external packed vec
73 | Mat(int w, void* data, size_t elemsize, int elempack, Allocator* allocator = 0);
74 | // external packed image
75 | Mat(int w, int h, void* data, size_t elemsize, int elempack, Allocator* allocator = 0);
76 | // external packed dim
77 | Mat(int w, int h, int c, void* data, size_t elemsize, int elempack, Allocator* allocator = 0);
78 | // release
79 | ~Mat();
80 | // assign
81 | Mat& operator=(const Mat& m);
82 | // set all
83 | void fill(float v);
84 | void fill(int v);
85 | #if __ARM_NEON
86 | void fill(float32x4_t _v);
87 | #endif // __ARM_NEON
88 | template void fill(T v);
89 | // deep copy
90 | Mat clone(Allocator* allocator = 0) const;
91 | // reshape vec
92 | Mat reshape(int w, Allocator* allocator = 0) const;
93 | // reshape image
94 | Mat reshape(int w, int h, Allocator* allocator = 0) const;
95 | // reshape dim
96 | Mat reshape(int w, int h, int c, Allocator* allocator = 0) const;
97 | // allocate vec
98 | void create(int w, size_t elemsize = 4u, Allocator* allocator = 0);
99 | // allocate image
100 | void create(int w, int h, size_t elemsize = 4u, Allocator* allocator = 0);
101 | // allocate dim
102 | void create(int w, int h, int c, size_t elemsize = 4u, Allocator* allocator = 0);
103 | // allocate packed vec
104 | void create(int w, size_t elemsize, int elempack, Allocator* allocator = 0);
105 | // allocate packed image
106 | void create(int w, int h, size_t elemsize, int elempack, Allocator* allocator = 0);
107 | // allocate packed dim
108 | void create(int w, int h, int c, size_t elemsize, int elempack, Allocator* allocator = 0);
109 | // allocate like
110 | void create_like(const Mat& m, Allocator* allocator = 0);
111 | #if NCNN_VULKAN
112 | // allocate like
113 | void create_like(const VkMat& m, Allocator* allocator = 0);
114 | #endif // NCNN_VULKAN
115 | // refcount++
116 | void addref();
117 | // refcount--
118 | void release();
119 |
120 | bool empty() const;
121 | size_t total() const;
122 |
123 | // data reference
124 | Mat channel(int c);
125 | const Mat channel(int c) const;
126 | float* row(int y);
127 | const float* row(int y) const;
128 | template T* row(int y);
129 | template const T* row(int y) const;
130 |
131 | // range reference
132 | Mat channel_range(int c, int channels);
133 | const Mat channel_range(int c, int channels) const;
134 | Mat row_range(int y, int rows);
135 | const Mat row_range(int y, int rows) const;
136 | Mat range(int x, int n);
137 | const Mat range(int x, int n) const;
138 |
139 | // access raw data
140 | template operator T*();
141 | template operator const T*() const;
142 |
143 | // convenient access float vec element
144 | float& operator[](int i);
145 | const float& operator[](int i) const;
146 |
147 | #if NCNN_PIXEL
148 | enum
149 | {
150 | PIXEL_CONVERT_SHIFT = 16,
151 | PIXEL_FORMAT_MASK = 0x0000ffff,
152 | PIXEL_CONVERT_MASK = 0xffff0000,
153 |
154 | PIXEL_RGB = 1,
155 | PIXEL_BGR = 2,
156 | PIXEL_GRAY = 3,
157 | PIXEL_RGBA = 4,
158 |
159 | PIXEL_RGB2BGR = PIXEL_RGB | (PIXEL_BGR << PIXEL_CONVERT_SHIFT),
160 | PIXEL_RGB2GRAY = PIXEL_RGB | (PIXEL_GRAY << PIXEL_CONVERT_SHIFT),
161 | PIXEL_RGB2RGBA = PIXEL_RGB | (PIXEL_RGBA << PIXEL_CONVERT_SHIFT),
162 |
163 | PIXEL_BGR2RGB = PIXEL_BGR | (PIXEL_RGB << PIXEL_CONVERT_SHIFT),
164 | PIXEL_BGR2GRAY = PIXEL_BGR | (PIXEL_GRAY << PIXEL_CONVERT_SHIFT),
165 | PIXEL_BGR2RGBA = PIXEL_BGR | (PIXEL_RGBA << PIXEL_CONVERT_SHIFT),
166 |
167 | PIXEL_GRAY2RGB = PIXEL_GRAY | (PIXEL_RGB << PIXEL_CONVERT_SHIFT),
168 | PIXEL_GRAY2BGR = PIXEL_GRAY | (PIXEL_BGR << PIXEL_CONVERT_SHIFT),
169 | PIXEL_GRAY2RGBA = PIXEL_GRAY | (PIXEL_RGBA << PIXEL_CONVERT_SHIFT),
170 |
171 | PIXEL_RGBA2RGB = PIXEL_RGBA | (PIXEL_RGB << PIXEL_CONVERT_SHIFT),
172 | PIXEL_RGBA2BGR = PIXEL_RGBA | (PIXEL_BGR << PIXEL_CONVERT_SHIFT),
173 | PIXEL_RGBA2GRAY = PIXEL_RGBA | (PIXEL_GRAY << PIXEL_CONVERT_SHIFT),
174 | };
175 | // convenient construct from pixel data
176 | static Mat from_pixels(const unsigned char* pixels, int type, int w, int h, Allocator* allocator = 0);
177 | // convenient construct from pixel data with stride(bytes-per-row) parameter
178 | static Mat from_pixels(const unsigned char* pixels, int type, int w, int h, int stride, Allocator* allocator = 0);
179 | // convenient construct from pixel data and resize to specific size
180 | static Mat from_pixels_resize(const unsigned char* pixels, int type, int w, int h, int target_width, int target_height, Allocator* allocator = 0);
181 | // convenient construct from pixel data and resize to specific size with stride(bytes-per-row) parameter
182 | static Mat from_pixels_resize(const unsigned char* pixels, int type, int w, int h, int stride, int target_width, int target_height, Allocator* allocator = 0);
183 |
184 | // convenient export to pixel data
185 | void to_pixels(unsigned char* pixels, int type) const;
186 | // convenient export to pixel data with stride(bytes-per-row) parameter
187 | void to_pixels(unsigned char* pixels, int type, int stride) const;
188 | // convenient export to pixel data and resize to specific size
189 | void to_pixels_resize(unsigned char* pixels, int type, int target_width, int target_height) const;
190 | // convenient export to pixel data and resize to specific size with stride(bytes-per-row) parameter
191 | void to_pixels_resize(unsigned char* pixels, int type, int target_width, int target_height, int target_stride) const;
192 |
193 | #if __ANDROID_API__ >= 9
194 | // convenient construct from android Bitmap
195 | static Mat from_android_bitmap(JNIEnv* env, jobject bitmap, int type_to, Allocator* allocator = 0);
196 | // convenient construct from android Bitmap and resize to specific size
197 | static Mat from_android_bitmap_resize(JNIEnv* env, jobject bitmap, int type_to, int target_width, int target_height, Allocator* allocator = 0);
198 | // convenient export to android Bitmap and resize to the android Bitmap size
199 | void to_android_bitmap(JNIEnv* env, jobject bitmap, int type_from) const;
200 | #endif // __ANDROID_API__ >= 9
201 | #endif // NCNN_PIXEL
202 |
203 | // substract channel-wise mean values, then multiply by normalize values, pass 0 to skip
204 | void substract_mean_normalize(const float* mean_vals, const float* norm_vals);
205 |
206 | // convenient construct from half precisoin floating point data
207 | static Mat from_float16(const unsigned short* data, int size);
208 |
209 | // pointer to the data
210 | void* data;
211 |
212 | // pointer to the reference counter
213 | // when points to user-allocated data, the pointer is NULL
214 | int* refcount;
215 |
216 | // element size in bytes
217 | // 4 = float32/int32
218 | // 2 = float16
219 | // 1 = int8/uint8
220 | // 0 = empty
221 | size_t elemsize;
222 |
223 | // packed count inside element
224 | // c/1-h-w-1 h/1-w-1 w/1-1 scalar
225 | // c/4-h-w-4 h/4-w-4 w/4-4 sse/neon
226 | // c/8-h-w-8 h/8-w-8 w/8-8 avx/fp16
227 | int elempack;
228 |
229 | // the allocator
230 | Allocator* allocator;
231 |
232 | // the dimensionality
233 | int dims;
234 |
235 | int w;
236 | int h;
237 | int c;
238 |
239 | size_t cstep;
240 | };
241 |
242 | #if NCNN_VULKAN
243 |
244 | // the three dimension matrix, vulkan version
245 | class VkMat
246 | {
247 | public:
248 | // empty
249 | VkMat();
250 | // vec
251 | VkMat(int w, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
252 | // image
253 | VkMat(int w, int h, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
254 | // dim
255 | VkMat(int w, int h, int c, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
256 | // packed vec
257 | VkMat(int w, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
258 | // packed image
259 | VkMat(int w, int h, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
260 | // packed dim
261 | VkMat(int w, int h, int c, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
262 | // copy
263 | VkMat(const VkMat& m);
264 | // external vec
265 | VkMat(int w, VkBufferMemory* data, size_t offset, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
266 | // external image
267 | VkMat(int w, int h, VkBufferMemory* data, size_t offset, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
268 | // external dim
269 | VkMat(int w, int h, int c, VkBufferMemory* data, size_t offset, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
270 | // external packed vec
271 | VkMat(int w, VkBufferMemory* data, size_t offset, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
272 | // external packed image
273 | VkMat(int w, int h, VkBufferMemory* data, size_t offset, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
274 | // external packed dim
275 | VkMat(int w, int h, int c, VkBufferMemory* data, size_t offset, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
276 | // release
277 | ~VkMat();
278 | // assign
279 | VkMat& operator=(const VkMat& m);
280 | // allocate vec
281 | void create(int w, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
282 | // allocate image
283 | void create(int w, int h, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
284 | // allocate dim
285 | void create(int w, int h, int c, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator);
286 | // allocate packed vec
287 | void create(int w, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
288 | // allocate packed image
289 | void create(int w, int h, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
290 | // allocate packed dim
291 | void create(int w, int h, int c, size_t elemsize, int elempack, VkAllocator* allocator, VkAllocator* staging_allocator);
292 | // allocate like
293 | void create_like(const Mat& m, VkAllocator* allocator, VkAllocator* staging_allocator);
294 | // allocate like
295 | void create_like(const VkMat& m, VkAllocator* allocator, VkAllocator* staging_allocator);
296 |
297 | // staging buffer
298 | void prepare_staging_buffer();
299 | void discard_staging_buffer();
300 |
301 | // copy
302 | void upload(const Mat& m);
303 | void download(Mat& m) const;
304 |
305 | // mapped
306 | Mat mapped() const;
307 | void* mapped_ptr() const;
308 |
309 | // refcount++
310 | void addref();
311 | // refcount--
312 | void release();
313 |
314 | bool empty() const;
315 | size_t total() const;
316 |
317 | // data reference
318 | VkMat channel(int c);
319 | const VkMat channel(int c) const;
320 |
321 | // range reference
322 | VkMat channel_range(int c, int channels);
323 | const VkMat channel_range(int c, int channels) const;
324 | VkMat row_range(int y, int rows);
325 | const VkMat row_range(int y, int rows) const;
326 | VkMat range(int x, int n);
327 | const VkMat range(int x, int n) const;
328 |
329 | // low-level reference
330 | VkBuffer buffer() const;
331 | size_t buffer_offset() const;
332 | VkBuffer staging_buffer() const;
333 | size_t staging_buffer_offset() const;
334 |
335 | // device buffer
336 | VkBufferMemory* data;
337 | // subrange offset
338 | size_t offset;
339 |
340 | // staging buffer
341 | VkBufferMemory* staging_data;
342 |
343 | // pointer to the reference counter
344 | // when points to user-allocated data, the pointer is NULL
345 | int* refcount;
346 | int* staging_refcount;
347 |
348 | // element size in bytes
349 | // 4 = float32/int32
350 | // 2 = float16
351 | // 1 = int8/uint8
352 | // 0 = empty
353 | size_t elemsize;
354 |
355 | // packed count inside element
356 | // c/1-h-w-1 h/1-w-1 w/1-1 scalar
357 | // c/4-h-w-4 h/4-w-4 w/4-4 sse/neon
358 | // c/8-h-w-8 h/8-w-8 w/8-8 avx/fp16
359 | int elempack;
360 |
361 | // the allocator
362 | VkAllocator* allocator;
363 | VkAllocator* staging_allocator;
364 |
365 | // the dimensionality
366 | int dims;
367 |
368 | int w;
369 | int h;
370 | int c;
371 |
372 | size_t cstep;
373 | };
374 |
375 | // type for vulkan specialization constant and push constant
376 | union vk_specialization_type { int i; float f; uint32_t u32; };
377 | union vk_constant_type { int i; float f; };
378 | #endif // NCNN_VULKAN
379 |
380 | // misc function
381 | #if NCNN_PIXEL
382 | // convert yuv420sp(nv21) to rgb, the fast approximate version
383 | void yuv420sp2rgb(const unsigned char* yuv420sp, int w, int h, unsigned char* rgb);
384 | // image pixel bilinear resize
385 | void resize_bilinear_c1(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h);
386 | void resize_bilinear_c2(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h);
387 | void resize_bilinear_c3(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h);
388 | void resize_bilinear_c4(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h);
389 | // image pixel bilinear resize with stride(bytes-per-row) parameter
390 | void resize_bilinear_c1(const unsigned char* src, int srcw, int srch, int srcstride, unsigned char* dst, int w, int h, int stride);
391 | void resize_bilinear_c2(const unsigned char* src, int srcw, int srch, int srcstride, unsigned char* dst, int w, int h, int stride);
392 | void resize_bilinear_c3(const unsigned char* src, int srcw, int srch, int srcstride, unsigned char* dst, int w, int h, int stride);
393 | void resize_bilinear_c4(const unsigned char* src, int srcw, int srch, int srcstride, unsigned char* dst, int w, int h, int stride);
394 | // image pixel bilinear resize, convenient wrapper for yuv420sp(nv21)
395 | void resize_bilinear_yuv420sp(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h);
396 | #endif // NCNN_PIXEL
397 | #if NCNN_PIXEL_ROTATE
398 | // type is the from type, 6 means rotating from 6 to 1
399 | //
400 | // 1 2 3 4 5 6 7 8
401 | //
402 | // 888888 888888 88 88 8888888888 88 88 8888888888
403 | // 88 88 88 88 88 88 88 88 88 88 88 88
404 | // 8888 8888 8888 8888 88 8888888888 8888888888 88
405 | // 88 88 88 88
406 | // 88 88 888888 888888
407 | //
408 | // ref http://sylvana.net/jpegcrop/exif_orientation.html
409 | // image pixel kanna rotate
410 | void kanna_rotate_c1(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h, int type);
411 | void kanna_rotate_c2(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h, int type);
412 | void kanna_rotate_c3(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h, int type);
413 | void kanna_rotate_c4(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h, int type);
414 | // image pixel kanna rotate with stride(bytes-per-row) parameter
415 | void kanna_rotate_c1(const unsigned char* src, int srcw, int srch, int srcstride, unsigned char* dst, int w, int h, int stride, int type);
416 | void kanna_rotate_c2(const unsigned char* src, int srcw, int srch, int srcstride, unsigned char* dst, int w, int h, int stride, int type);
417 | void kanna_rotate_c3(const unsigned char* src, int srcw, int srch, int srcstride, unsigned char* dst, int w, int h, int stride, int type);
418 | void kanna_rotate_c4(const unsigned char* src, int srcw, int srch, int srcstride, unsigned char* dst, int w, int h, int stride, int type);
419 | // image pixel kanna rotate, convenient wrapper for yuv420sp(nv21)
420 | void kanna_rotate_yuv420sp(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h, int type);
421 | #endif // NCNN_PIXEL_ROTATE
422 |
423 | // mat process
424 | enum
425 | {
426 | BORDER_CONSTANT = 0,
427 | BORDER_REPLICATE = 1,
428 | };
429 | void copy_make_border(const Mat& src, Mat& dst, int top, int bottom, int left, int right, int type, float v, const Option& opt = Option());
430 | void copy_cut_border(const Mat& src, Mat& dst, int top, int bottom, int left, int right, const Option& opt = Option());
431 | void resize_bilinear(const Mat& src, Mat& dst, int w, int h, const Option& opt = Option());
432 | void resize_bicubic(const Mat& src, Mat& dst, int w, int h, const Option& opt = Option());
433 | void convert_packing(const Mat& src, Mat& dst, int elempack, const Option& opt = Option());
434 | void cast_float32_to_float16(const Mat& src, Mat& dst, const Option& opt = Option());
435 | void cast_float16_to_float32(const Mat& src, Mat& dst, const Option& opt = Option());
436 |
437 | inline Mat::Mat()
438 | : data(0), refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
439 | {
440 | }
441 |
442 | inline Mat::Mat(int _w, size_t _elemsize, Allocator* _allocator)
443 | : data(0), refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
444 | {
445 | create(_w, _elemsize, _allocator);
446 | }
447 |
448 | inline Mat::Mat(int _w, int _h, size_t _elemsize, Allocator* _allocator)
449 | : data(0), refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
450 | {
451 | create(_w, _h, _elemsize, _allocator);
452 | }
453 |
454 | inline Mat::Mat(int _w, int _h, int _c, size_t _elemsize, Allocator* _allocator)
455 | : data(0), refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
456 | {
457 | create(_w, _h, _c, _elemsize, _allocator);
458 | }
459 |
460 | inline Mat::Mat(int _w, size_t _elemsize, int _elempack, Allocator* _allocator)
461 | : data(0), refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
462 | {
463 | create(_w, _elemsize, _elempack, _allocator);
464 | }
465 |
466 | inline Mat::Mat(int _w, int _h, size_t _elemsize, int _elempack, Allocator* _allocator)
467 | : data(0), refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
468 | {
469 | create(_w, _h, _elemsize, _elempack, _allocator);
470 | }
471 |
472 | inline Mat::Mat(int _w, int _h, int _c, size_t _elemsize, int _elempack, Allocator* _allocator)
473 | : data(0), refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
474 | {
475 | create(_w, _h, _c, _elemsize, _elempack, _allocator);
476 | }
477 |
478 | inline Mat::Mat(const Mat& m)
479 | : data(m.data), refcount(m.refcount), elemsize(m.elemsize), elempack(m.elempack), allocator(m.allocator), dims(m.dims), w(m.w), h(m.h), c(m.c), cstep(m.cstep)
480 | {
481 | if (refcount)
482 | NCNN_XADD(refcount, 1);
483 | }
484 |
485 | inline Mat::Mat(int _w, void* _data, size_t _elemsize, Allocator* _allocator)
486 | : data(_data), refcount(0), elemsize(_elemsize), elempack(1), allocator(_allocator), dims(1), w(_w), h(1), c(1)
487 | {
488 | cstep = w;
489 | }
490 |
491 | inline Mat::Mat(int _w, int _h, void* _data, size_t _elemsize, Allocator* _allocator)
492 | : data(_data), refcount(0), elemsize(_elemsize), elempack(1), allocator(_allocator), dims(2), w(_w), h(_h), c(1)
493 | {
494 | cstep = w * h;
495 | }
496 |
497 | inline Mat::Mat(int _w, int _h, int _c, void* _data, size_t _elemsize, Allocator* _allocator)
498 | : data(_data), refcount(0), elemsize(_elemsize), elempack(1), allocator(_allocator), dims(3), w(_w), h(_h), c(_c)
499 | {
500 | cstep = alignSize(w * h * elemsize, 16) / elemsize;
501 | }
502 |
503 | inline Mat::Mat(int _w, void* _data, size_t _elemsize, int _elempack, Allocator* _allocator)
504 | : data(_data), refcount(0), elemsize(_elemsize), elempack(_elempack), allocator(_allocator), dims(1), w(_w), h(1), c(1)
505 | {
506 | cstep = w;
507 | }
508 |
509 | inline Mat::Mat(int _w, int _h, void* _data, size_t _elemsize, int _elempack, Allocator* _allocator)
510 | : data(_data), refcount(0), elemsize(_elemsize), elempack(_elempack), allocator(_allocator), dims(2), w(_w), h(_h), c(1)
511 | {
512 | cstep = w * h;
513 | }
514 |
515 | inline Mat::Mat(int _w, int _h, int _c, void* _data, size_t _elemsize, int _elempack, Allocator* _allocator)
516 | : data(_data), refcount(0), elemsize(_elemsize), elempack(_elempack), allocator(_allocator), dims(3), w(_w), h(_h), c(_c)
517 | {
518 | cstep = alignSize(w * h * elemsize, 16) / elemsize;
519 | }
520 |
521 | inline Mat::~Mat()
522 | {
523 | release();
524 | }
525 |
526 | inline Mat& Mat::operator=(const Mat& m)
527 | {
528 | if (this == &m)
529 | return *this;
530 |
531 | if (m.refcount)
532 | NCNN_XADD(m.refcount, 1);
533 |
534 | release();
535 |
536 | data = m.data;
537 | refcount = m.refcount;
538 | elemsize = m.elemsize;
539 | elempack = m.elempack;
540 | allocator = m.allocator;
541 |
542 | dims = m.dims;
543 | w = m.w;
544 | h = m.h;
545 | c = m.c;
546 |
547 | cstep = m.cstep;
548 |
549 | return *this;
550 | }
551 |
552 | inline void Mat::fill(float _v)
553 | {
554 | int size = (int)total();
555 | float* ptr = (float*)data;
556 |
557 | #if __ARM_NEON
558 | int nn = size >> 2;
559 | int remain = size - (nn << 2);
560 | #else
561 | int remain = size;
562 | #endif // __ARM_NEON
563 |
564 | #if __ARM_NEON
565 | float32x4_t _c = vdupq_n_f32(_v);
566 | #if __aarch64__
567 | if (nn > 0)
568 | {
569 | asm volatile (
570 | "0: \n"
571 | "subs %w0, %w0, #1 \n"
572 | "st1 {%4.4s}, [%1], #16 \n"
573 | "bne 0b \n"
574 | : "=r"(nn), // %0
575 | "=r"(ptr) // %1
576 | : "0"(nn),
577 | "1"(ptr),
578 | "w"(_c) // %4
579 | : "cc", "memory"
580 | );
581 | }
582 | #else
583 | if (nn > 0)
584 | {
585 | asm volatile(
586 | "0: \n"
587 | "subs %0, #1 \n"
588 | "vst1.f32 {%e4-%f4}, [%1 :128]!\n"
589 | "bne 0b \n"
590 | : "=r"(nn), // %0
591 | "=r"(ptr) // %1
592 | : "0"(nn),
593 | "1"(ptr),
594 | "w"(_c) // %4
595 | : "cc", "memory"
596 | );
597 | }
598 | #endif // __aarch64__
599 | #endif // __ARM_NEON
600 | for (; remain>0; remain--)
601 | {
602 | *ptr++ = _v;
603 | }
604 | }
605 |
606 | inline void Mat::fill(int _v)
607 | {
608 | int size = (int)total();
609 | int* ptr = (int*)data;
610 |
611 | #if __ARM_NEON
612 | int nn = size >> 2;
613 | int remain = size - (nn << 2);
614 | #else
615 | int remain = size;
616 | #endif // __ARM_NEON
617 |
618 | #if __ARM_NEON
619 | int32x4_t _c = vdupq_n_s32(_v);
620 | #if __aarch64__
621 | if (nn > 0)
622 | {
623 | asm volatile (
624 | "0: \n"
625 | "subs %w0, %w0, #1 \n"
626 | "st1 {%4.4s}, [%1], #16 \n"
627 | "bne 0b \n"
628 | : "=r"(nn), // %0
629 | "=r"(ptr) // %1
630 | : "0"(nn),
631 | "1"(ptr),
632 | "w"(_c) // %4
633 | : "cc", "memory"
634 | );
635 | }
636 | #else
637 | if (nn > 0)
638 | {
639 | asm volatile(
640 | "0: \n"
641 | "subs %0, #1 \n"
642 | "vst1.s32 {%e4-%f4}, [%1 :128]!\n"
643 | "bne 0b \n"
644 | : "=r"(nn), // %0
645 | "=r"(ptr) // %1
646 | : "0"(nn),
647 | "1"(ptr),
648 | "w"(_c) // %4
649 | : "cc", "memory"
650 | );
651 | }
652 | #endif // __aarch64__
653 | #endif // __ARM_NEON
654 | for (; remain>0; remain--)
655 | {
656 | *ptr++ = _v;
657 | }
658 | }
659 |
660 | #if __ARM_NEON
661 | inline void Mat::fill(float32x4_t _v)
662 | {
663 | int size = total();
664 | float* ptr = (float*)data;
665 | for (int i=0; i
674 | inline void Mat::fill(T _v)
675 | {
676 | int size = total();
677 | T* ptr = (T*)data;
678 | for (int i=0; i 0)
698 | {
699 | memcpy(m.data, data, total() * elemsize);
700 | }
701 |
702 | return m;
703 | }
704 |
705 | inline Mat Mat::reshape(int _w, Allocator* _allocator) const
706 | {
707 | if (w * h * c != _w)
708 | return Mat();
709 |
710 | if (dims == 3 && cstep != (size_t)w * h)
711 | {
712 | Mat m;
713 | m.create(_w, elemsize, elempack, _allocator);
714 |
715 | // flatten
716 | for (int i=0; i 0)
832 | {
833 | size_t totalsize = alignSize(total() * elemsize, 4);
834 | if (allocator)
835 | data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
836 | else
837 | data = fastMalloc(totalsize + (int)sizeof(*refcount));
838 | refcount = (int*)(((unsigned char*)data) + totalsize);
839 | *refcount = 1;
840 | }
841 | }
842 |
843 | inline void Mat::create(int _w, int _h, size_t _elemsize, Allocator* _allocator)
844 | {
845 | if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
846 | return;
847 |
848 | release();
849 |
850 | elemsize = _elemsize;
851 | elempack = 1;
852 | allocator = _allocator;
853 |
854 | dims = 2;
855 | w = _w;
856 | h = _h;
857 | c = 1;
858 |
859 | cstep = w * h;
860 |
861 | if (total() > 0)
862 | {
863 | size_t totalsize = alignSize(total() * elemsize, 4);
864 | if (allocator)
865 | data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
866 | else
867 | data = fastMalloc(totalsize + (int)sizeof(*refcount));
868 | refcount = (int*)(((unsigned char*)data) + totalsize);
869 | *refcount = 1;
870 | }
871 | }
872 |
873 | inline void Mat::create(int _w, int _h, int _c, size_t _elemsize, Allocator* _allocator)
874 | {
875 | if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
876 | return;
877 |
878 | release();
879 |
880 | elemsize = _elemsize;
881 | elempack = 1;
882 | allocator = _allocator;
883 |
884 | dims = 3;
885 | w = _w;
886 | h = _h;
887 | c = _c;
888 |
889 | cstep = alignSize(w * h * elemsize, 16) / elemsize;
890 |
891 | if (total() > 0)
892 | {
893 | size_t totalsize = alignSize(total() * elemsize, 4);
894 | if (allocator)
895 | data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
896 | else
897 | data = fastMalloc(totalsize + (int)sizeof(*refcount));
898 | refcount = (int*)(((unsigned char*)data) + totalsize);
899 | *refcount = 1;
900 | }
901 | }
902 |
903 | inline void Mat::create(int _w, size_t _elemsize, int _elempack, Allocator* _allocator)
904 | {
905 | if (dims == 1 && w == _w && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
906 | return;
907 |
908 | release();
909 |
910 | elemsize = _elemsize;
911 | elempack = _elempack;
912 | allocator = _allocator;
913 |
914 | dims = 1;
915 | w = _w;
916 | h = 1;
917 | c = 1;
918 |
919 | cstep = w;
920 |
921 | if (total() > 0)
922 | {
923 | size_t totalsize = alignSize(total() * elemsize, 4);
924 | if (allocator)
925 | data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
926 | else
927 | data = fastMalloc(totalsize + (int)sizeof(*refcount));
928 | refcount = (int*)(((unsigned char*)data) + totalsize);
929 | *refcount = 1;
930 | }
931 | }
932 |
933 | inline void Mat::create(int _w, int _h, size_t _elemsize, int _elempack, Allocator* _allocator)
934 | {
935 | if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
936 | return;
937 |
938 | release();
939 |
940 | elemsize = _elemsize;
941 | elempack = _elempack;
942 | allocator = _allocator;
943 |
944 | dims = 2;
945 | w = _w;
946 | h = _h;
947 | c = 1;
948 |
949 | cstep = w * h;
950 |
951 | if (total() > 0)
952 | {
953 | size_t totalsize = alignSize(total() * elemsize, 4);
954 | if (allocator)
955 | data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
956 | else
957 | data = fastMalloc(totalsize + (int)sizeof(*refcount));
958 | refcount = (int*)(((unsigned char*)data) + totalsize);
959 | *refcount = 1;
960 | }
961 | }
962 |
963 | inline void Mat::create(int _w, int _h, int _c, size_t _elemsize, int _elempack, Allocator* _allocator)
964 | {
965 | if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
966 | return;
967 |
968 | release();
969 |
970 | elemsize = _elemsize;
971 | elempack = _elempack;
972 | allocator = _allocator;
973 |
974 | dims = 3;
975 | w = _w;
976 | h = _h;
977 | c = _c;
978 |
979 | cstep = alignSize(w * h * elemsize, 16) / elemsize;
980 |
981 | if (total() > 0)
982 | {
983 | size_t totalsize = alignSize(total() * elemsize, 4);
984 | if (allocator)
985 | data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
986 | else
987 | data = fastMalloc(totalsize + (int)sizeof(*refcount));
988 | refcount = (int*)(((unsigned char*)data) + totalsize);
989 | *refcount = 1;
990 | }
991 | }
992 |
993 | inline void Mat::create_like(const Mat& m, Allocator* _allocator)
994 | {
995 | if (m.dims == 1)
996 | create(m.w, m.elemsize, m.elempack, _allocator);
997 | else if (m.dims == 2)
998 | create(m.w, m.h, m.elemsize, m.elempack, _allocator);
999 | else if (m.dims == 3)
1000 | create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator);
1001 | }
1002 |
1003 | #if NCNN_VULKAN
1004 | inline void Mat::create_like(const VkMat& m, Allocator* _allocator)
1005 | {
1006 | if (m.dims == 1)
1007 | create(m.w, m.elemsize, m.elempack, _allocator);
1008 | else if (m.dims == 2)
1009 | create(m.w, m.h, m.elemsize, m.elempack, _allocator);
1010 | else if (m.dims == 3)
1011 | create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator);
1012 | }
1013 | #endif // NCNN_VULKAN
1014 |
1015 | inline void Mat::addref()
1016 | {
1017 | if (refcount)
1018 | NCNN_XADD(refcount, 1);
1019 | }
1020 |
1021 | inline void Mat::release()
1022 | {
1023 | if (refcount && NCNN_XADD(refcount, -1) == 1)
1024 | {
1025 | if (allocator)
1026 | allocator->fastFree(data);
1027 | else
1028 | fastFree(data);
1029 | }
1030 |
1031 | data = 0;
1032 |
1033 | elemsize = 0;
1034 | elempack = 0;
1035 |
1036 | dims = 0;
1037 | w = 0;
1038 | h = 0;
1039 | c = 0;
1040 |
1041 | cstep = 0;
1042 |
1043 | refcount = 0;
1044 | }
1045 |
1046 | inline bool Mat::empty() const
1047 | {
1048 | return data == 0 || total() == 0;
1049 | }
1050 |
1051 | inline size_t Mat::total() const
1052 | {
1053 | return cstep * c;
1054 | }
1055 |
1056 | inline Mat Mat::channel(int _c)
1057 | {
1058 | return Mat(w, h, (unsigned char*)data + cstep * _c * elemsize, elemsize, elempack, allocator);
1059 | }
1060 |
1061 | inline const Mat Mat::channel(int _c) const
1062 | {
1063 | return Mat(w, h, (unsigned char*)data + cstep * _c * elemsize, elemsize, elempack, allocator);
1064 | }
1065 |
1066 | inline float* Mat::row(int y)
1067 | {
1068 | return (float*)((unsigned char*)data + w * y * elemsize);
1069 | }
1070 |
1071 | inline const float* Mat::row(int y) const
1072 | {
1073 | return (const float*)((unsigned char*)data + w * y * elemsize);
1074 | }
1075 |
1076 | template
1077 | inline T* Mat::row(int y)
1078 | {
1079 | return (T*)((unsigned char*)data + w * y * elemsize);
1080 | }
1081 |
1082 | template
1083 | inline const T* Mat::row(int y) const
1084 | {
1085 | return (const T*)((unsigned char*)data + w * y * elemsize);
1086 | }
1087 |
1088 | inline Mat Mat::channel_range(int _c, int channels)
1089 | {
1090 | return Mat(w, h, channels, (unsigned char*)data + cstep * _c * elemsize, elemsize, elempack, allocator);
1091 | }
1092 |
1093 | inline const Mat Mat::channel_range(int _c, int channels) const
1094 | {
1095 | return Mat(w, h, channels, (unsigned char*)data + cstep * _c * elemsize, elemsize, elempack, allocator);
1096 | }
1097 |
1098 | inline Mat Mat::row_range(int y, int rows)
1099 | {
1100 | return Mat(w, rows, (unsigned char*)data + w * y * elemsize, elemsize, elempack, allocator);
1101 | }
1102 |
1103 | inline const Mat Mat::row_range(int y, int rows) const
1104 | {
1105 | return Mat(w, rows, (unsigned char*)data + w * y * elemsize, elemsize, elempack, allocator);
1106 | }
1107 |
1108 | inline Mat Mat::range(int x, int n)
1109 | {
1110 | return Mat(n, (unsigned char*)data + x * elemsize, elemsize, elempack, allocator);
1111 | }
1112 |
1113 | inline const Mat Mat::range(int x, int n) const
1114 | {
1115 | return Mat(n, (unsigned char*)data + x * elemsize, elemsize, elempack, allocator);
1116 | }
1117 |
1118 | template
1119 | inline Mat::operator T*()
1120 | {
1121 | return (T*)data;
1122 | }
1123 |
1124 | template
1125 | inline Mat::operator const T*() const
1126 | {
1127 | return (const T*)data;
1128 | }
1129 |
1130 | inline float& Mat::operator[](int i)
1131 | {
1132 | return ((float*)data)[i];
1133 | }
1134 |
1135 | inline const float& Mat::operator[](int i) const
1136 | {
1137 | return ((const float*)data)[i];
1138 | }
1139 |
1140 | #if NCNN_VULKAN
1141 |
1142 | inline VkMat::VkMat()
1143 | : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
1144 | {
1145 | }
1146 |
1147 | inline VkMat::VkMat(int _w, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1148 | : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
1149 | {
1150 | create(_w, _elemsize, _allocator, _staging_allocator);
1151 | }
1152 |
1153 | inline VkMat::VkMat(int _w, int _h, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1154 | : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
1155 | {
1156 | create(_w, _h, _elemsize, _allocator, _staging_allocator);
1157 | }
1158 |
1159 | inline VkMat::VkMat(int _w, int _h, int _c, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1160 | : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
1161 | {
1162 | create(_w, _h, _c, _elemsize, _allocator, _staging_allocator);
1163 | }
1164 |
1165 | inline VkMat::VkMat(int _w, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1166 | : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
1167 | {
1168 | create(_w, _elemsize, _elempack, _allocator, _staging_allocator);
1169 | }
1170 |
1171 | inline VkMat::VkMat(int _w, int _h, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1172 | : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
1173 | {
1174 | create(_w, _h, _elemsize, _elempack, _allocator, _staging_allocator);
1175 | }
1176 |
1177 | inline VkMat::VkMat(int _w, int _h, int _c, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1178 | : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0), elemsize(0), elempack(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0)
1179 | {
1180 | create(_w, _h, _c, _elemsize, _elempack, _allocator, _staging_allocator);
1181 | }
1182 |
1183 | inline VkMat::VkMat(const VkMat& m)
1184 | : data(m.data), offset(m.offset), staging_data(m.staging_data), refcount(m.refcount), staging_refcount(m.staging_refcount), elemsize(m.elemsize), elempack(m.elempack), allocator(m.allocator), staging_allocator(m.staging_allocator), dims(m.dims), w(m.w), h(m.h), c(m.c)
1185 | {
1186 | if (refcount)
1187 | NCNN_XADD(refcount, 1);
1188 |
1189 | if (staging_refcount)
1190 | NCNN_XADD(staging_refcount, 1);
1191 |
1192 | cstep = m.cstep;
1193 | }
1194 |
1195 | inline VkMat::VkMat(int _w, VkBufferMemory* _data, size_t _offset, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1196 | : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), elempack(1), allocator(_allocator), staging_allocator(_staging_allocator), dims(1), w(_w), h(1), c(1)
1197 | {
1198 | cstep = w;
1199 | }
1200 |
1201 | inline VkMat::VkMat(int _w, int _h, VkBufferMemory* _data, size_t _offset, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1202 | : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), elempack(1), allocator(_allocator), staging_allocator(_staging_allocator), dims(2), w(_w), h(_h), c(1)
1203 | {
1204 | cstep = w * h;
1205 | }
1206 |
1207 | inline VkMat::VkMat(int _w, int _h, int _c, VkBufferMemory* _data, size_t _offset, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1208 | : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), elempack(1), allocator(_allocator), staging_allocator(_staging_allocator), dims(3), w(_w), h(_h), c(_c)
1209 | {
1210 | cstep = alignSize(w * h * elemsize, 16) / elemsize;
1211 | }
1212 |
1213 | inline VkMat::VkMat(int _w, VkBufferMemory* _data, size_t _offset, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1214 | : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), elempack(_elempack), allocator(_allocator), staging_allocator(_staging_allocator), dims(1), w(_w), h(1), c(1)
1215 | {
1216 | cstep = w;
1217 | }
1218 |
1219 | inline VkMat::VkMat(int _w, int _h, VkBufferMemory* _data, size_t _offset, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1220 | : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), elempack(_elempack), allocator(_allocator), staging_allocator(_staging_allocator), dims(2), w(_w), h(_h), c(1)
1221 | {
1222 | cstep = w * h;
1223 | }
1224 |
1225 | inline VkMat::VkMat(int _w, int _h, int _c, VkBufferMemory* _data, size_t _offset, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1226 | : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), elempack(_elempack), allocator(_allocator), staging_allocator(_staging_allocator), dims(3), w(_w), h(_h), c(_c)
1227 | {
1228 | cstep = alignSize(w * h * elemsize, 16) / elemsize;
1229 | }
1230 |
1231 | inline VkMat::~VkMat()
1232 | {
1233 | release();
1234 | }
1235 |
1236 | inline VkMat& VkMat::operator=(const VkMat& m)
1237 | {
1238 | if (this == &m)
1239 | return *this;
1240 |
1241 | if (m.refcount)
1242 | NCNN_XADD(m.refcount, 1);
1243 |
1244 | if (m.staging_refcount)
1245 | NCNN_XADD(m.staging_refcount, 1);
1246 |
1247 | release();
1248 |
1249 | data = m.data;
1250 | offset = m.offset;
1251 | staging_data = m.staging_data;
1252 | refcount = m.refcount;
1253 | staging_refcount = m.staging_refcount;
1254 | elemsize = m.elemsize;
1255 | elempack = m.elempack;
1256 | allocator = m.allocator;
1257 | staging_allocator = m.staging_allocator;
1258 |
1259 | dims = m.dims;
1260 | w = m.w;
1261 | h = m.h;
1262 | c = m.c;
1263 |
1264 | cstep = m.cstep;
1265 |
1266 | return *this;
1267 | }
1268 |
1269 | inline void VkMat::create(int _w, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1270 | {
1271 | if (dims == 1 && w == _w && elemsize == _elemsize && elempack == 1 && allocator == _allocator && staging_allocator == _staging_allocator)
1272 | return;
1273 |
1274 | release();
1275 |
1276 | elemsize = _elemsize;
1277 | elempack = 1;
1278 | allocator = _allocator;
1279 | staging_allocator = _staging_allocator;
1280 |
1281 | dims = 1;
1282 | w = _w;
1283 | h = 1;
1284 | c = 1;
1285 |
1286 | cstep = w;
1287 |
1288 | if (total() > 0)
1289 | {
1290 | size_t totalsize = alignSize(total() * elemsize, 4);
1291 |
1292 | data = allocator->fastMalloc(totalsize);
1293 | offset = 0;
1294 |
1295 | refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
1296 | *refcount = 1;
1297 | }
1298 | }
1299 |
1300 | inline void VkMat::create(int _w, int _h, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1301 | {
1302 | if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == 1 && allocator == _allocator && staging_allocator == _staging_allocator)
1303 | return;
1304 |
1305 | release();
1306 |
1307 | elemsize = _elemsize;
1308 | elempack = 1;
1309 | allocator = _allocator;
1310 | staging_allocator = _staging_allocator;
1311 |
1312 | dims = 2;
1313 | w = _w;
1314 | h = _h;
1315 | c = 1;
1316 |
1317 | cstep = w * h;
1318 |
1319 | if (total() > 0)
1320 | {
1321 | size_t totalsize = alignSize(total() * elemsize, 4);
1322 |
1323 | data = allocator->fastMalloc(totalsize);
1324 | offset = 0;
1325 |
1326 | refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
1327 | *refcount = 1;
1328 | }
1329 | }
1330 |
1331 | inline void VkMat::create(int _w, int _h, int _c, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1332 | {
1333 | if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == 1 && allocator == _allocator && staging_allocator == _staging_allocator)
1334 | return;
1335 |
1336 | release();
1337 |
1338 | elemsize = _elemsize;
1339 | elempack = 1;
1340 | allocator = _allocator;
1341 | staging_allocator = _staging_allocator;
1342 |
1343 | dims = 3;
1344 | w = _w;
1345 | h = _h;
1346 | c = _c;
1347 |
1348 | cstep = alignSize(w * h * elemsize, 16) / elemsize;
1349 |
1350 | if (total() > 0)
1351 | {
1352 | size_t totalsize = alignSize(total() * elemsize, 4);
1353 |
1354 | data = allocator->fastMalloc(totalsize);
1355 | offset = 0;
1356 |
1357 | refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
1358 | *refcount = 1;
1359 | }
1360 | }
1361 |
1362 | inline void VkMat::create(int _w, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1363 | {
1364 | if (dims == 1 && w == _w && elemsize == _elemsize && elempack == _elempack && allocator == _allocator && staging_allocator == _staging_allocator)
1365 | return;
1366 |
1367 | release();
1368 |
1369 | elemsize = _elemsize;
1370 | elempack = _elempack;
1371 | allocator = _allocator;
1372 | staging_allocator = _staging_allocator;
1373 |
1374 | dims = 1;
1375 | w = _w;
1376 | h = 1;
1377 | c = 1;
1378 |
1379 | cstep = w;
1380 |
1381 | if (total() > 0)
1382 | {
1383 | size_t totalsize = alignSize(total() * elemsize, 4);
1384 |
1385 | data = allocator->fastMalloc(totalsize);
1386 | offset = 0;
1387 |
1388 | refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
1389 | *refcount = 1;
1390 | }
1391 | }
1392 |
1393 | inline void VkMat::create(int _w, int _h, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1394 | {
1395 | if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == _elempack && allocator == _allocator && staging_allocator == _staging_allocator)
1396 | return;
1397 |
1398 | release();
1399 |
1400 | elemsize = _elemsize;
1401 | elempack = _elempack;
1402 | allocator = _allocator;
1403 | staging_allocator = _staging_allocator;
1404 |
1405 | dims = 2;
1406 | w = _w;
1407 | h = _h;
1408 | c = 1;
1409 |
1410 | cstep = w * h;
1411 |
1412 | if (total() > 0)
1413 | {
1414 | size_t totalsize = alignSize(total() * elemsize, 4);
1415 |
1416 | data = allocator->fastMalloc(totalsize);
1417 | offset = 0;
1418 |
1419 | refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
1420 | *refcount = 1;
1421 | }
1422 | }
1423 |
1424 | inline void VkMat::create(int _w, int _h, int _c, size_t _elemsize, int _elempack, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1425 | {
1426 | if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == _elempack && allocator == _allocator && staging_allocator == _staging_allocator)
1427 | return;
1428 |
1429 | release();
1430 |
1431 | elemsize = _elemsize;
1432 | elempack = _elempack;
1433 | allocator = _allocator;
1434 | staging_allocator = _staging_allocator;
1435 |
1436 | dims = 3;
1437 | w = _w;
1438 | h = _h;
1439 | c = _c;
1440 |
1441 | cstep = alignSize(w * h * elemsize, 16) / elemsize;
1442 |
1443 | if (total() > 0)
1444 | {
1445 | size_t totalsize = alignSize(total() * elemsize, 4);
1446 |
1447 | data = allocator->fastMalloc(totalsize);
1448 | offset = 0;
1449 |
1450 | refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
1451 | *refcount = 1;
1452 | }
1453 | }
1454 |
1455 | inline void VkMat::create_like(const Mat& m, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1456 | {
1457 | if (m.dims == 1)
1458 | create(m.w, m.elemsize, m.elempack, _allocator, _staging_allocator);
1459 | else if (m.dims == 2)
1460 | create(m.w, m.h, m.elemsize, m.elempack, _allocator, _staging_allocator);
1461 | else if (m.dims == 3)
1462 | create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator, _staging_allocator);
1463 | }
1464 |
1465 | inline void VkMat::create_like(const VkMat& m, VkAllocator* _allocator, VkAllocator* _staging_allocator)
1466 | {
1467 | if (m.dims == 1)
1468 | create(m.w, m.elemsize, m.elempack, _allocator, _staging_allocator);
1469 | else if (m.dims == 2)
1470 | create(m.w, m.h, m.elemsize, m.elempack, _allocator, _staging_allocator);
1471 | else if (m.dims == 3)
1472 | create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator, _staging_allocator);
1473 | }
1474 |
1475 | inline void VkMat::prepare_staging_buffer()
1476 | {
1477 | if (allocator->mappable)
1478 | return;
1479 |
1480 | if (staging_allocator && staging_data)
1481 | return;
1482 |
1483 | size_t totalsize = alignSize(total() * elemsize, 4);
1484 | staging_data = staging_allocator->fastMalloc(totalsize);
1485 |
1486 | staging_refcount = (int*)((unsigned char*)staging_data + offsetof(VkBufferMemory, refcount));
1487 | *staging_refcount = 1;
1488 | }
1489 |
1490 | inline void VkMat::discard_staging_buffer()
1491 | {
1492 | if (allocator->mappable)
1493 | return;
1494 |
1495 | if (staging_refcount && NCNN_XADD(staging_refcount, -1) == 1)
1496 | {
1497 | if (staging_allocator && staging_data)
1498 | {
1499 | staging_allocator->fastFree(staging_data);
1500 | }
1501 | }
1502 |
1503 | staging_data = 0;
1504 | staging_refcount = 0;
1505 | }
1506 |
1507 | inline void VkMat::upload(const Mat& m)
1508 | {
1509 | memcpy(mapped_ptr(), m.data, m.total() * m.elemsize);
1510 | }
1511 |
1512 | inline void VkMat::download(Mat& m) const
1513 | {
1514 | memcpy(m.data, mapped_ptr(), total() * elemsize);
1515 | }
1516 |
1517 | inline Mat VkMat::mapped() const
1518 | {
1519 | if (dims == 1)
1520 | return Mat(w, mapped_ptr(), elemsize, elempack, 0);
1521 |
1522 | if (dims == 2)
1523 | return Mat(w, h, mapped_ptr(), elemsize, elempack, 0);
1524 |
1525 | if (dims == 3)
1526 | return Mat(w, h, c, mapped_ptr(), elemsize, elempack, 0);
1527 |
1528 | return Mat();
1529 | }
1530 |
1531 | inline void* VkMat::mapped_ptr() const
1532 | {
1533 | VkBufferMemory* mappable_data = allocator->mappable ? data : staging_data;
1534 | return (unsigned char*)mappable_data->mapped_ptr + mappable_data->offset + offset;
1535 | }
1536 |
1537 | inline void VkMat::addref()
1538 | {
1539 | if (refcount)
1540 | NCNN_XADD(refcount, 1);
1541 |
1542 | if (staging_refcount)
1543 | NCNN_XADD(staging_refcount, 1);
1544 | }
1545 |
1546 | inline void VkMat::release()
1547 | {
1548 | if (refcount && NCNN_XADD(refcount, -1) == 1)
1549 | {
1550 | if (allocator && data)
1551 | {
1552 | allocator->fastFree(data);
1553 | }
1554 | }
1555 |
1556 | if (staging_refcount && NCNN_XADD(staging_refcount, -1) == 1)
1557 | {
1558 | if (staging_allocator && staging_data)
1559 | {
1560 | staging_allocator->fastFree(staging_data);
1561 | }
1562 | }
1563 |
1564 | data = 0;
1565 | offset = 0;
1566 | staging_data = 0;
1567 |
1568 | elemsize = 0;
1569 | elempack = 0;
1570 |
1571 | dims = 0;
1572 | w = 0;
1573 | h = 0;
1574 | c = 0;
1575 |
1576 | cstep = 0;
1577 |
1578 | refcount = 0;
1579 | staging_refcount = 0;
1580 | }
1581 |
1582 | inline bool VkMat::empty() const
1583 | {
1584 | return data == 0 || total() == 0;
1585 | }
1586 |
1587 | inline size_t VkMat::total() const
1588 | {
1589 | return cstep * c;
1590 | }
1591 |
1592 | inline VkMat VkMat::channel(int _c)
1593 | {
1594 | return VkMat(w, h, data, cstep * _c * elemsize, elemsize, elempack, allocator, staging_allocator);
1595 | }
1596 |
1597 | inline const VkMat VkMat::channel(int _c) const
1598 | {
1599 | return VkMat(w, h, data, cstep * _c * elemsize, elemsize, elempack, allocator, staging_allocator);
1600 | }
1601 |
1602 | inline VkMat VkMat::channel_range(int _c, int channels)
1603 | {
1604 | return VkMat(w, h, channels, data, cstep * _c * elemsize, elemsize, elempack, allocator, staging_allocator);
1605 | }
1606 |
1607 | inline const VkMat VkMat::channel_range(int _c, int channels) const
1608 | {
1609 | return VkMat(w, h, channels, data, cstep * _c * elemsize, elemsize, elempack, allocator, staging_allocator);
1610 | }
1611 |
1612 | inline VkMat VkMat::row_range(int y, int rows)
1613 | {
1614 | return VkMat(w, rows, data, w * y * elemsize, elemsize, elempack, allocator, staging_allocator);
1615 | }
1616 |
1617 | inline const VkMat VkMat::row_range(int y, int rows) const
1618 | {
1619 | return VkMat(w, rows, data, w * y * elemsize, elemsize, elempack, allocator, staging_allocator);
1620 | }
1621 |
1622 | inline VkMat VkMat::range(int x, int n)
1623 | {
1624 | return VkMat(n, data, x * elemsize, elemsize, elempack, allocator, staging_allocator);
1625 | }
1626 |
1627 | inline const VkMat VkMat::range(int x, int n) const
1628 | {
1629 | return VkMat(n, data, x * elemsize, elemsize, elempack, allocator, staging_allocator);
1630 | }
1631 |
1632 | inline VkBuffer VkMat::buffer() const
1633 | {
1634 | return data->buffer;
1635 | }
1636 |
1637 | inline size_t VkMat::buffer_offset() const
1638 | {
1639 | return data->offset + offset;
1640 | }
1641 |
1642 | inline VkBuffer VkMat::staging_buffer() const
1643 | {
1644 | return staging_data->buffer;
1645 | }
1646 |
1647 | inline size_t VkMat::staging_buffer_offset() const
1648 | {
1649 | return staging_data->offset;
1650 | }
1651 | #endif // NCNN_VULKAN
1652 |
1653 | } // namespace ncnn
1654 |
1655 | #endif // NCNN_MAT_H
1656 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/modelbin.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_MODELBIN_H
16 | #define NCNN_MODELBIN_H
17 |
18 | #include "mat.h"
19 |
20 | namespace ncnn {
21 |
22 | class DataReader;
23 | class ModelBin
24 | {
25 | public:
26 | virtual ~ModelBin();
27 | // element type
28 | // 0 = auto
29 | // 1 = float32
30 | // 2 = float16
31 | // 3 = int8
32 | // load vec
33 | virtual Mat load(int w, int type) const = 0;
34 | // load image
35 | virtual Mat load(int w, int h, int type) const;
36 | // load dim
37 | virtual Mat load(int w, int h, int c, int type) const;
38 | };
39 |
40 | class ModelBinFromDataReader : public ModelBin
41 | {
42 | public:
43 | ModelBinFromDataReader(const DataReader& dr);
44 |
45 | virtual Mat load(int w, int type) const;
46 |
47 | protected:
48 | const DataReader& dr;
49 | };
50 |
51 | class ModelBinFromMatArray : public ModelBin
52 | {
53 | public:
54 | // construct from weight blob array
55 | ModelBinFromMatArray(const Mat* weights);
56 |
57 | virtual Mat load(int w, int type) const;
58 |
59 | protected:
60 | mutable const Mat* weights;
61 | };
62 |
63 | } // namespace ncnn
64 |
65 | #endif // NCNN_MODELBIN_H
66 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/net.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_NET_H
16 | #define NCNN_NET_H
17 |
18 | #include
19 | #include
20 | #include "platform.h"
21 | #include "blob.h"
22 | #include "layer.h"
23 | #include "mat.h"
24 | #include "option.h"
25 |
26 | #if __ANDROID_API__ >= 9
27 | #include
28 | #endif // __ANDROID_API__ >= 9
29 |
30 | namespace ncnn {
31 |
32 | #if NCNN_VULKAN
33 | class VkCompute;
34 | #endif // NCNN_VULKAN
35 | class DataReader;
36 | class Extractor;
37 | class Net
38 | {
39 | public:
40 | // empty init
41 | Net();
42 | // clear and destroy
43 | ~Net();
44 |
45 | public:
46 | // option can be changed before loading
47 | Option opt;
48 |
49 | #if NCNN_VULKAN
50 | // set gpu device by index
51 | void set_vulkan_device(int device_index);
52 |
53 | // set gpu device by device handle, no owner transfer
54 | void set_vulkan_device(const VulkanDevice* vkdev);
55 |
56 | const VulkanDevice* vulkan_device() const;
57 | #endif // NCNN_VULKAN
58 |
59 | #if NCNN_STRING
60 | // register custom layer by layer type name
61 | // return 0 if success
62 | int register_custom_layer(const char* type, layer_creator_func creator);
63 | #endif // NCNN_STRING
64 | // register custom layer by layer type
65 | // return 0 if success
66 | int register_custom_layer(int index, layer_creator_func creator);
67 |
68 | #if NCNN_STRING
69 | int load_param(const DataReader& dr);
70 | #endif // NCNN_STRING
71 |
72 | int load_param_bin(const DataReader& dr);
73 |
74 | int load_model(const DataReader& dr);
75 |
76 | #if NCNN_STDIO
77 | #if NCNN_STRING
78 | // load network structure from plain param file
79 | // return 0 if success
80 | int load_param(FILE* fp);
81 | int load_param(const char* protopath);
82 | int load_param_mem(const char* mem);
83 | #endif // NCNN_STRING
84 | // load network structure from binary param file
85 | // return 0 if success
86 | int load_param_bin(FILE* fp);
87 | int load_param_bin(const char* protopath);
88 |
89 | // load network weight data from model file
90 | // return 0 if success
91 | int load_model(FILE* fp);
92 | int load_model(const char* modelpath);
93 | #endif // NCNN_STDIO
94 |
95 | // load network structure from external memory
96 | // memory pointer must be 32-bit aligned
97 | // return bytes consumed
98 | int load_param(const unsigned char* mem);
99 |
100 | // reference network weight data from external memory
101 | // weight data is not copied but referenced
102 | // so external memory should be retained when used
103 | // memory pointer must be 32-bit aligned
104 | // return bytes consumed
105 | int load_model(const unsigned char* mem);
106 |
107 | #if __ANDROID_API__ >= 9
108 | #if NCNN_STRING
109 | // convenient load network structure from android asset plain param file
110 | int load_param(AAsset* asset);
111 | int load_param(AAssetManager* mgr, const char* assetpath);
112 | #endif // NCNN_STRING
113 | // convenient load network structure from android asset binary param file
114 | int load_param_bin(AAsset* asset);
115 | int load_param_bin(AAssetManager* mgr, const char* assetpath);
116 |
117 | // convenient load network weight data from android asset model file
118 | int load_model(AAsset* asset);
119 | int load_model(AAssetManager* mgr, const char* assetpath);
120 | #endif // __ANDROID_API__ >= 9
121 |
122 | // unload network structure and weight data
123 | void clear();
124 |
125 | // construct an Extractor from network
126 | Extractor create_extractor() const;
127 |
128 | protected:
129 | // parse the structure of network
130 | // fuse int8 op dequantize and quantize by requantize
131 | int fuse_network();
132 |
133 | #if NCNN_VULKAN
134 |
135 | int upload_model();
136 |
137 | int create_pipeline();
138 |
139 | int destroy_pipeline();
140 |
141 | #endif // NCNN_VULKAN
142 |
143 | friend class Extractor;
144 | #if NCNN_STRING
145 | int find_blob_index_by_name(const char* name) const;
146 | int find_layer_index_by_name(const char* name) const;
147 | int custom_layer_to_index(const char* type);
148 | Layer* create_custom_layer(const char* type);
149 | #endif // NCNN_STRING
150 | Layer* create_custom_layer(int index);
151 | int forward_layer(int layer_index, std::vector& blob_mats, Option& opt) const;
152 |
153 | #if NCNN_VULKAN
154 | int forward_layer(int layer_index, std::vector& blob_mats, std::vector& blob_mats_gpu, VkCompute& cmd, Option& opt) const;
155 | #endif // NCNN_VULKAN
156 |
157 | protected:
158 | std::vector blobs;
159 | std::vector layers;
160 |
161 | std::vector custom_layer_registry;
162 |
163 | #if NCNN_VULKAN
164 | const VulkanDevice* vkdev;
165 |
166 | VkAllocator* weight_vkallocator;
167 | VkAllocator* weight_staging_vkallocator;
168 |
169 | ncnn::Layer* cast_float32_to_float16;
170 | ncnn::Layer* cast_float16_to_float32;
171 | ncnn::Layer* packing_pack1;
172 | ncnn::Layer* packing_pack4;
173 | #endif // NCNN_VULKAN
174 | };
175 |
176 | class Extractor
177 | {
178 | public:
179 | // enable light mode
180 | // intermediate blob will be recycled when enabled
181 | // enabled by default
182 | void set_light_mode(bool enable);
183 |
184 | // set thread count for this extractor
185 | // this will overwrite the global setting
186 | // default count is system depended
187 | void set_num_threads(int num_threads);
188 |
189 | // set blob memory allocator
190 | void set_blob_allocator(Allocator* allocator);
191 |
192 | // set workspace memory allocator
193 | void set_workspace_allocator(Allocator* allocator);
194 |
195 | #if NCNN_VULKAN
196 | void set_vulkan_compute(bool enable);
197 |
198 | void set_blob_vkallocator(VkAllocator* allocator);
199 |
200 | void set_workspace_vkallocator(VkAllocator* allocator);
201 |
202 | void set_staging_vkallocator(VkAllocator* allocator);
203 | #endif // NCNN_VULKAN
204 |
205 | #if NCNN_STRING
206 | // set input by blob name
207 | // return 0 if success
208 | int input(const char* blob_name, const Mat& in);
209 |
210 | // get result by blob name
211 | // return 0 if success
212 | int extract(const char* blob_name, Mat& feat);
213 | #endif // NCNN_STRING
214 |
215 | // set input by blob index
216 | // return 0 if success
217 | int input(int blob_index, const Mat& in);
218 |
219 | // get result by blob index
220 | // return 0 if success
221 | int extract(int blob_index, Mat& feat);
222 |
223 | #if NCNN_VULKAN
224 | #if NCNN_STRING
225 | // set input by blob name
226 | // return 0 if success
227 | int input(const char* blob_name, const VkMat& in);
228 |
229 | // get result by blob name
230 | // return 0 if success
231 | int extract(const char* blob_name, VkMat& feat, VkCompute& cmd);
232 | #endif // NCNN_STRING
233 |
234 | // set input by blob index
235 | // return 0 if success
236 | int input(int blob_index, const VkMat& in);
237 |
238 | // get result by blob index
239 | // return 0 if success
240 | int extract(int blob_index, VkMat& feat, VkCompute& cmd);
241 | #endif // NCNN_VULKAN
242 |
243 | protected:
244 | friend Extractor Net::create_extractor() const;
245 | Extractor(const Net* net, int blob_count);
246 |
247 | private:
248 | const Net* net;
249 | std::vector blob_mats;
250 | Option opt;
251 |
252 | #if NCNN_VULKAN
253 | std::vector blob_mats_gpu;
254 | #endif // NCNN_VULKAN
255 | };
256 |
257 | } // namespace ncnn
258 |
259 | #endif // NCNN_NET_H
260 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/opencv.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_OPENCV_H
16 | #define NCNN_OPENCV_H
17 |
18 | #include "platform.h"
19 |
20 | #if NCNN_OPENCV
21 |
22 | #include
23 | #include
24 | #include "mat.h"
25 |
26 | #if defined(_MSC_VER) || defined(__GNUC__)
27 | #pragma push_macro("min")
28 | #pragma push_macro("max")
29 | #undef min
30 | #undef max
31 | #endif
32 |
33 | // minimal opencv style data structure implementation
34 | namespace cv
35 | {
36 |
37 | struct Size
38 | {
39 | Size() : width(0), height(0) {}
40 | Size(int _w, int _h) : width(_w), height(_h) {}
41 |
42 | int width;
43 | int height;
44 | };
45 |
46 | template
47 | struct Rect_
48 | {
49 | Rect_() : x(0), y(0), width(0), height(0) {}
50 | Rect_(_Tp _x, _Tp _y, _Tp _w, _Tp _h) : x(_x), y(_y), width(_w), height(_h) {}
51 |
52 | _Tp x;
53 | _Tp y;
54 | _Tp width;
55 | _Tp height;
56 |
57 | // area
58 | _Tp area() const
59 | {
60 | return width * height;
61 | }
62 | };
63 |
64 | template static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
65 | {
66 | _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y);
67 | a.width = std::min(a.x + a.width, b.x + b.width) - x1;
68 | a.height = std::min(a.y + a.height, b.y + b.height) - y1;
69 | a.x = x1; a.y = y1;
70 | if( a.width <= 0 || a.height <= 0 )
71 | a = Rect_<_Tp>();
72 | return a;
73 | }
74 |
75 | template static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
76 | {
77 | _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y);
78 | a.width = std::max(a.x + a.width, b.x + b.width) - x1;
79 | a.height = std::max(a.y + a.height, b.y + b.height) - y1;
80 | a.x = x1; a.y = y1;
81 | return a;
82 | }
83 |
84 | template static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
85 | {
86 | Rect_<_Tp> c = a;
87 | return c &= b;
88 | }
89 |
90 | template static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
91 | {
92 | Rect_<_Tp> c = a;
93 | return c |= b;
94 | }
95 |
96 | typedef Rect_ Rect;
97 | typedef Rect_ Rect2f;
98 |
99 | template
100 | struct Point_
101 | {
102 | Point_() : x(0), y(0) {}
103 | Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {}
104 |
105 | _Tp x;
106 | _Tp y;
107 | };
108 |
109 | typedef Point_ Point;
110 | typedef Point_ Point2f;
111 |
112 | #define CV_8UC1 1
113 | #define CV_8UC3 3
114 | #define CV_8UC4 4
115 | #define CV_32FC1 4
116 |
117 | struct Mat
118 | {
119 | Mat() : data(0), refcount(0), rows(0), cols(0), c(0) {}
120 |
121 | Mat(int _rows, int _cols, int flags) : data(0), refcount(0)
122 | {
123 | create(_rows, _cols, flags);
124 | }
125 |
126 | // copy
127 | Mat(const Mat& m) : data(m.data), refcount(m.refcount)
128 | {
129 | if (refcount)
130 | NCNN_XADD(refcount, 1);
131 |
132 | rows = m.rows;
133 | cols = m.cols;
134 | c = m.c;
135 | }
136 |
137 | Mat(int _rows, int _cols, int flags, void* _data) : data((unsigned char*)_data), refcount(0)
138 | {
139 | rows = _rows;
140 | cols = _cols;
141 | c = flags;
142 | }
143 |
144 | ~Mat()
145 | {
146 | release();
147 | }
148 |
149 | // assign
150 | Mat& operator=(const Mat& m)
151 | {
152 | if (this == &m)
153 | return *this;
154 |
155 | if (m.refcount)
156 | NCNN_XADD(m.refcount, 1);
157 |
158 | release();
159 |
160 | data = m.data;
161 | refcount = m.refcount;
162 |
163 | rows = m.rows;
164 | cols = m.cols;
165 | c = m.c;
166 |
167 | return *this;
168 | }
169 |
170 | void create(int _rows, int _cols, int flags)
171 | {
172 | release();
173 |
174 | rows = _rows;
175 | cols = _cols;
176 | c = flags;
177 |
178 | if (total() > 0)
179 | {
180 | // refcount address must be aligned, so we expand totalsize here
181 | size_t totalsize = (total() + 3) >> 2 << 2;
182 | data = (unsigned char*)ncnn::fastMalloc(totalsize + (int)sizeof(*refcount));
183 | refcount = (int*)(((unsigned char*)data) + totalsize);
184 | *refcount = 1;
185 | }
186 | }
187 |
188 | void release()
189 | {
190 | if (refcount && NCNN_XADD(refcount, -1) == 1)
191 | ncnn::fastFree(data);
192 |
193 | data = 0;
194 |
195 | rows = 0;
196 | cols = 0;
197 | c = 0;
198 |
199 | refcount = 0;
200 | }
201 |
202 | Mat clone() const
203 | {
204 | if (empty())
205 | return Mat();
206 |
207 | Mat m(rows, cols, c);
208 |
209 | if (total() > 0)
210 | {
211 | memcpy(m.data, data, total());
212 | }
213 |
214 | return m;
215 | }
216 |
217 | bool empty() const { return data == 0 || total() == 0; }
218 |
219 | int channels() const { return c; }
220 |
221 | size_t total() const { return cols * rows * c; }
222 |
223 | const unsigned char* ptr(int y) const { return data + y * cols * c; }
224 |
225 | unsigned char* ptr(int y) { return data + y * cols * c; }
226 |
227 | // roi
228 | Mat operator()( const Rect& roi ) const
229 | {
230 | if (empty())
231 | return Mat();
232 |
233 | Mat m(roi.height, roi.width, c);
234 |
235 | int sy = roi.y;
236 | for (int y = 0; y < roi.height; y++)
237 | {
238 | const unsigned char* sptr = ptr(sy) + roi.x * c;
239 | unsigned char* dptr = m.ptr(y);
240 | memcpy(dptr, sptr, roi.width * c);
241 | sy++;
242 | }
243 |
244 | return m;
245 | }
246 |
247 | unsigned char* data;
248 |
249 | // pointer to the reference counter;
250 | // when points to user-allocated data, the pointer is NULL
251 | int* refcount;
252 |
253 | int rows;
254 | int cols;
255 |
256 | int c;
257 |
258 | };
259 |
260 | #define CV_LOAD_IMAGE_GRAYSCALE 1
261 | #define CV_LOAD_IMAGE_COLOR 3
262 | Mat imread(const std::string& path, int flags);
263 | void imwrite(const std::string& path, const Mat& m);
264 |
265 | #if NCNN_PIXEL
266 | void resize(const Mat& src, Mat& dst, const Size& size, float sw = 0.f, float sh = 0.f, int flags = 0);
267 | #endif // NCNN_PIXEL
268 |
269 | } // namespace cv
270 |
271 | #if defined(_MSC_VER) || defined(__GNUC__)
272 | #pragma pop_macro("min")
273 | #pragma pop_macro("max")
274 | #endif
275 |
276 | #endif // NCNN_OPENCV
277 |
278 | #endif // NCNN_OPENCV_H
279 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/option.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_OPTION_H
16 | #define NCNN_OPTION_H
17 |
18 | #include "platform.h"
19 |
20 | namespace ncnn {
21 |
22 | #if NCNN_VULKAN
23 | class VkAllocator;
24 | #endif // NCNN_VULKAN
25 |
26 | class Allocator;
27 | class Option
28 | {
29 | public:
30 | // default option
31 | Option();
32 |
33 | public:
34 | // light mode
35 | // intermediate blob will be recycled when enabled
36 | // enabled by default
37 | bool lightmode;
38 |
39 | // thread count
40 | // default value is the one returned by get_cpu_count()
41 | int num_threads;
42 |
43 | // blob memory allocator
44 | Allocator* blob_allocator;
45 |
46 | // workspace memory allocator
47 | Allocator* workspace_allocator;
48 |
49 | #if NCNN_VULKAN
50 | // blob memory allocator
51 | VkAllocator* blob_vkallocator;
52 |
53 | // workspace memory allocator
54 | VkAllocator* workspace_vkallocator;
55 |
56 | // staging memory allocator
57 | VkAllocator* staging_vkallocator;
58 | #endif // NCNN_VULKAN
59 |
60 | // enable winograd convolution optimization
61 | // improve convolution 3x3 stride1 performace, may consume more memory
62 | // changes should be applied before loading network structure and weight
63 | // enabled by default
64 | bool use_winograd_convolution;
65 |
66 | // enable sgemm convolution optimization
67 | // improve convolution 1x1 stride1 performace, may consume more memory
68 | // changes should be applied before loading network structure and weight
69 | // enabled by default
70 | bool use_sgemm_convolution;
71 |
72 | // enable quantized int8 inference
73 | // use low-precision int8 path for quantized model
74 | // changes should be applied before loading network structure and weight
75 | // enabled by default
76 | bool use_int8_inference;
77 |
78 | // enable vulkan compute
79 | bool use_vulkan_compute;
80 |
81 | // enable options for gpu inference
82 | bool use_fp16_packed;
83 | bool use_fp16_storage;
84 | bool use_fp16_arithmetic;
85 | bool use_int8_storage;
86 | bool use_int8_arithmetic;
87 |
88 | //
89 | bool use_packing_layout;
90 | };
91 |
92 | } // namespace ncnn
93 |
94 | #endif // NCNN_OPTION_H
95 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/paramdict.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_PARAMDICT_H
16 | #define NCNN_PARAMDICT_H
17 |
18 | #include "mat.h"
19 |
20 | // at most 32 parameters
21 | #define NCNN_MAX_PARAM_COUNT 32
22 |
23 | namespace ncnn {
24 |
25 | class DataReader;
26 | class Net;
27 | class ParamDict
28 | {
29 | public:
30 | // empty
31 | ParamDict();
32 |
33 | // get int
34 | int get(int id, int def) const;
35 | // get float
36 | float get(int id, float def) const;
37 | // get array
38 | Mat get(int id, const Mat& def) const;
39 |
40 | // set int
41 | void set(int id, int i);
42 | // set float
43 | void set(int id, float f);
44 | // set array
45 | void set(int id, const Mat& v);
46 |
47 | protected:
48 | friend class Net;
49 |
50 | void clear();
51 |
52 | int load_param(const DataReader& dr);
53 | int load_param_bin(const DataReader& dr);
54 |
55 | protected:
56 | struct
57 | {
58 | // 0 = null
59 | // 1 = int/float
60 | // 2 = int
61 | // 3 = float
62 | // 4 = array of int/float
63 | // 5 = array of int
64 | // 6 = array of float
65 | int type;
66 | union { int i; float f; };
67 | Mat v;
68 | } params[NCNN_MAX_PARAM_COUNT];
69 | };
70 |
71 | } // namespace ncnn
72 |
73 | #endif // NCNN_PARAMDICT_H
74 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/pipeline.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_PIPELINE_H
16 | #define NCNN_PIPELINE_H
17 |
18 | #include "platform.h"
19 | #include "mat.h"
20 | #if NCNN_VULKAN
21 | #include
22 | #include "gpu.h"
23 | #endif // NCNN_VULKAN
24 |
25 | namespace ncnn {
26 |
27 | #if NCNN_VULKAN
28 | class Option;
29 | class Pipeline
30 | {
31 | public:
32 | Pipeline(const VulkanDevice* vkdev);
33 | ~Pipeline();
34 |
35 | public:
36 | void set_optimal_local_size_xyz(int w = 32, int h = 32, int c = 32);
37 | void set_local_size_xyz(int w, int h, int c);
38 |
39 | int create(const uint32_t* spv_data, size_t spv_data_size, const char* entry_name,
40 | const std::vector& specializations, int binding_count, int push_constant_count);
41 | int create(VkShaderModule shader_module, const char* entry_name,
42 | const std::vector& specializations, int binding_count, int push_constant_count);
43 | int create(const char* name, const Option& opt, const std::vector& specializations,
44 | int binding_count, int push_constant_count);
45 | void destroy();
46 |
47 | protected:
48 | int create_descriptorset_layout(int binding_count);
49 | int create_pipeline_layout(int push_constant_count);
50 | int create_pipeline(VkShaderModule shader_module, const char* entry_name, const std::vector& specializations);
51 | int create_descriptor_update_template(int binding_count);
52 |
53 | public:
54 | const VulkanDevice* vkdev;
55 |
56 | // local shader module
57 | VkShaderModule local_shader_module;
58 |
59 | VkDescriptorSetLayout descriptorset_layout;
60 | VkPipelineLayout pipeline_layout;
61 |
62 | // op forward TODO use pipeline cache ?
63 | VkPipeline pipeline;
64 |
65 | VkDescriptorUpdateTemplateKHR descriptor_update_template;
66 |
67 | uint32_t local_size_x;
68 | uint32_t local_size_y;
69 | uint32_t local_size_z;
70 | };
71 |
72 | #if __ANDROID_API__ >= 26
73 | class VkCompute;
74 | class ImportAndroidHardwareBufferPipeline : private Pipeline
75 | {
76 | public:
77 | ImportAndroidHardwareBufferPipeline(const VulkanDevice* vkdev);
78 | ~ImportAndroidHardwareBufferPipeline();
79 |
80 | int create(AHardwareBuffer* hb, int type_to, int rotate_from, const Option& opt);
81 | void destroy();
82 |
83 | int create_image_memory_imageview(AHardwareBuffer* hb, VkImage* image, VkDeviceMemory* memory, VkImageView* imageView);
84 |
85 | friend class VkCompute;
86 |
87 | protected:
88 | int create_sampler();
89 | int create_descriptorset_layout();
90 | int create_descriptor_update_template();
91 |
92 | public:
93 | int w;
94 | int h;
95 | int outw;
96 | int outh;
97 | int outc;
98 | size_t out_elemsize;
99 | int out_elempack;
100 | int type_to;
101 | int rotate_from;
102 | VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties;
103 | VkAndroidHardwareBufferPropertiesANDROID bufferProperties;
104 |
105 | VkSamplerYcbcrConversionKHR samplerYcbcrConversion;
106 | VkSampler sampler;
107 | };
108 | #endif // __ANDROID_API__ >= 26
109 | #endif // NCNN_VULKAN
110 |
111 | } // namespace ncnn
112 |
113 | #endif // NCNN_PIPELINE_H
114 |
--------------------------------------------------------------------------------
/app/src/main/cpp/include/ncnn/platform.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NCNN_PLATFORM_H
16 | #define NCNN_PLATFORM_H
17 |
18 | #define NCNN_STDIO 1
19 | #define NCNN_STRING 1
20 | #define NCNN_OPENCV 0
21 | #define NCNN_BENCHMARK 0
22 | #define NCNN_PIXEL 1
23 | #define NCNN_PIXEL_ROTATE 1
24 | #define NCNN_VULKAN 0
25 | #define NCNN_REQUANT 0
26 | #define NCNN_AVX2 0
27 |
28 | #ifdef _WIN32
29 | #define WIN32_LEAN_AND_MEAN
30 | #include
31 | #include
32 | #else
33 | #include
34 | #endif
35 |
36 | #if __ANDROID_API__ >= 26
37 | #define VK_USE_PLATFORM_ANDROID_KHR
38 | #endif // __ANDROID_API__ >= 26
39 |
40 | namespace ncnn {
41 |
42 | #ifdef _WIN32
43 | class Mutex
44 | {
45 | public:
46 | Mutex() { InitializeSRWLock(&srwlock); }
47 | ~Mutex() {}
48 | void lock() { AcquireSRWLockExclusive(&srwlock); }
49 | void unlock() { ReleaseSRWLockExclusive(&srwlock); }
50 | private:
51 | friend class ConditionVariable;
52 | // NOTE SRWLock is available from windows vista
53 | SRWLOCK srwlock;
54 | };
55 | #else // _WIN32
56 | class Mutex
57 | {
58 | public:
59 | Mutex() { pthread_mutex_init(&mutex, 0); }
60 | ~Mutex() { pthread_mutex_destroy(&mutex); }
61 | void lock() { pthread_mutex_lock(&mutex); }
62 | void unlock() { pthread_mutex_unlock(&mutex); }
63 | private:
64 | friend class ConditionVariable;
65 | pthread_mutex_t mutex;
66 | };
67 | #endif // _WIN32
68 |
69 | class MutexLockGuard
70 | {
71 | public:
72 | MutexLockGuard(Mutex& _mutex) : mutex(_mutex) { mutex.lock(); }
73 | ~MutexLockGuard() { mutex.unlock(); }
74 | private:
75 | Mutex& mutex;
76 | };
77 |
78 | #if _WIN32
79 | class ConditionVariable
80 | {
81 | public:
82 | ConditionVariable() { InitializeConditionVariable(&condvar); }
83 | ~ConditionVariable() {}
84 | void wait(Mutex& mutex) { SleepConditionVariableSRW(&condvar, &mutex.srwlock, INFINITE, 0); }
85 | void broadcast() { WakeAllConditionVariable(&condvar); }
86 | void signal() { WakeConditionVariable(&condvar); }
87 | private:
88 | CONDITION_VARIABLE condvar;
89 | };
90 | #else // _WIN32
91 | class ConditionVariable
92 | {
93 | public:
94 | ConditionVariable() { pthread_cond_init(&cond, 0); }
95 | ~ConditionVariable() { pthread_cond_destroy(&cond); }
96 | void wait(Mutex& mutex) { pthread_cond_wait(&cond, &mutex.mutex); }
97 | void broadcast() { pthread_cond_broadcast(&cond); }
98 | void signal() { pthread_cond_signal(&cond); }
99 | private:
100 | pthread_cond_t cond;
101 | };
102 | #endif // _WIN32
103 |
104 | #if _WIN32
105 | static unsigned __stdcall start_wrapper(void* args);
106 | class Thread
107 | {
108 | public:
109 | Thread(void* (*start)(void*), void* args = 0) { _start = start; _args = args; handle = (HANDLE)_beginthreadex(0, 0, start_wrapper, this, 0, 0); }
110 | ~Thread() {}
111 | void join() { WaitForSingleObject(handle, INFINITE); CloseHandle(handle); }
112 | private:
113 | friend unsigned __stdcall start_wrapper(void* args)
114 | {
115 | Thread* t = (Thread*)args;
116 | t->_start(t->_args);
117 | return 0;
118 | }
119 | HANDLE handle;
120 | void* (*_start)(void*);
121 | void* _args;
122 | };
123 |
124 | #else // _WIN32
125 | class Thread
126 | {
127 | public:
128 | Thread(void* (*start)(void*), void* args = 0) { pthread_create(&t, 0, start, args); }
129 | ~Thread() {}
130 | void join() { pthread_join(t, 0); }
131 | private:
132 | pthread_t t;
133 | };
134 | #endif // _WIN32
135 |
136 | } // namespace ncnn
137 |
138 | #endif // NCNN_PLATFORM_H
139 |
--------------------------------------------------------------------------------
/app/src/main/cpp/yolov3-tiny-jni.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include
8 | #include
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | #include "platform.h"
15 | #include "net.h"
16 | #if NCNN_VULKAN
17 | #include "gpu.h"
18 | #endif // NCNN_VULKAN
19 |
20 | extern "C" {
21 |
22 | static ncnn::Net yolov3;
23 |
24 | //struct Object
25 | //{
26 | // cv::Rect_ rect;
27 | // int label;
28 | // float prob;
29 | //};
30 |
31 | JNIEXPORT jboolean JNICALL
32 | Java_com_example_yolov3tiny_yolov3Tiny_Init(JNIEnv *env, jobject obj, jstring param, jstring bin) {
33 | __android_log_print(ANDROID_LOG_DEBUG, "yolov3tinyJni", "enter the jni func");
34 |
35 | #if NCNN_VULKAN
36 | yolov3.opt.use_vulkan_compute = true;
37 | #endif // NCNN_VULKAN
38 |
39 | const char *param_path = env->GetStringUTFChars( param, NULL);
40 | if(param_path == NULL)
41 | return JNI_FALSE;
42 | __android_log_print(ANDROID_LOG_DEBUG, "yolov3tinyJni", "load_param %s", param_path);
43 |
44 | int ret = yolov3.load_param(param_path);
45 | __android_log_print(ANDROID_LOG_DEBUG, "yolov3tinyJni", "load_param result %d", ret);
46 | env->ReleaseStringUTFChars( param, param_path);
47 |
48 | const char *bin_path = env->GetStringUTFChars( bin, NULL);
49 | if(bin_path == NULL)
50 | return JNI_FALSE;
51 | __android_log_print(ANDROID_LOG_DEBUG, "yolov3tinyJni", "load_model %s", bin_path);
52 |
53 | int ret2 = yolov3.load_model(bin_path);
54 | __android_log_print(ANDROID_LOG_DEBUG, "yolov3tinyJni", "load_model result %d", ret2);
55 | env->ReleaseStringUTFChars( bin, bin_path);
56 | return JNI_TRUE;
57 | }
58 |
59 | JNIEXPORT jfloatArray JNICALL Java_com_example_yolov3tiny_yolov3Tiny_Detect(JNIEnv* env, jobject thiz, jobject bitmap)
60 | {
61 | const int target_size = 416; //input size
62 |
63 | AndroidBitmapInfo info;
64 | AndroidBitmap_getInfo(env, bitmap, &info);
65 | int width = info.width;
66 | int height = info.height;
67 | if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
68 | return NULL;
69 |
70 | void* indata;
71 | AndroidBitmap_lockPixels(env, bitmap, &indata);
72 |
73 | // const char *img_path = env->GetStringUTFChars( imgPath, NULL);
74 | // if(img_path == NULL)
75 | // return JNI_FALSE;
76 | // __android_log_print(ANDROID_LOG_DEBUG, "yolov3tinyJni", "load_img %s", img_path);
77 | //
78 | // cv::Mat m = cv::imread(img_path, CV_LOAD_IMAGE_COLOR);
79 | // env->ReleaseStringUTFChars( imgPath, img_path);
80 | // ncnn::Mat in = ncnn::Mat::from_pixels_resize(m.data, ncnn::Mat::PIXEL_BGR2RGB, m.cols, m.rows, input->w, input->h);
81 |
82 | //you can resize image in this cpp, or when reading image in java.
83 | //ncnn::Mat in = ncnn::Mat::from_pixels_resize((const unsigned char*)indata, ncnn::Mat::PIXEL_RGBA2RGB, width, height, target_size, target_size);
84 | ncnn::Mat in = ncnn::Mat::from_pixels((const unsigned char*)indata, ncnn::Mat::PIXEL_RGBA2RGB, width, height);
85 | __android_log_print(ANDROID_LOG_DEBUG, "yolov3tinyJni", "yolov3_predict_has_input1, in.w: %d; in.h: %d", in.w, in.h);
86 | AndroidBitmap_unlockPixels(env, bitmap);
87 |
88 | const float norm_vals[3] = {1 / 255.0, 1 / 255.0, 1 / 255.0};
89 | in.substract_mean_normalize(0, norm_vals);
90 | ncnn::Extractor ex = yolov3.create_extractor();
91 | ex.input("data",in);
92 | ex.set_light_mode(false);
93 | ex.set_num_threads(4);
94 |
95 | ncnn::Mat out;
96 | int result = ex.extract("yolo_23", out); //yolo_23 is the out_blob name in param file
97 | __android_log_print(ANDROID_LOG_DEBUG, "yolov3tinyJni", "extract result %d", result);
98 | if (result != 0)
99 | return NULL;
100 |
101 | int output_wsize = out.w;
102 | int output_hsize = out.h;
103 | jfloat *output[output_wsize * output_hsize];
104 | for(int i = 0; i< out.h; i++) {
105 | for (int j = 0; j < out.w; j++) {
106 | output[i*output_wsize + j] = &out.row(i)[j];
107 | }
108 | }
109 | jfloatArray jOutputData = env->NewFloatArray(output_wsize * output_hsize);
110 | if (jOutputData == nullptr) return nullptr;
111 | env->SetFloatArrayRegion(jOutputData, 0, output_wsize * output_hsize,
112 | reinterpret_cast(*output)); // copy
113 |
114 | return jOutputData;
115 |
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/yolov3tiny/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.yolov3tiny;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.content.Intent;
6 | import android.content.pm.PackageManager;
7 | import android.content.res.AssetManager;
8 | import android.graphics.Bitmap;
9 | import android.graphics.Canvas;
10 | import android.graphics.Color;
11 | import android.graphics.Paint;
12 | import android.net.Uri;
13 | import android.os.Bundle;
14 | import android.support.annotation.NonNull;
15 | import android.support.annotation.Nullable;
16 | import android.support.v4.app.ActivityCompat;
17 | import android.support.v4.content.ContextCompat;
18 | import android.text.method.ScrollingMovementMethod;
19 | import android.util.Log;
20 | import android.view.View;
21 | import android.widget.Button;
22 | import android.widget.ImageView;
23 | import android.widget.TextView;
24 | import android.widget.Toast;
25 |
26 | import com.bumptech.glide.load.engine.DiskCacheStrategy;
27 | import com.bumptech.glide.request.RequestOptions;
28 |
29 | import java.io.BufferedReader;
30 | import java.io.File;
31 | import java.io.FileOutputStream;
32 | import java.io.IOException;
33 | import java.io.InputStream;
34 | import java.io.InputStreamReader;
35 | import java.util.ArrayList;
36 | import java.util.Arrays;
37 | import java.util.List;
38 |
39 |
40 | public class MainActivity extends Activity {
41 | private static final String TAG = MainActivity.class.getName();
42 | private static final int SELECT_IMAGE = 1;
43 | private ImageView show_image;
44 | private TextView result_text;
45 | private boolean load_result = false;
46 | private int[] ddims = {1, 3, 416, 416};
47 | private int model_index = 1;
48 | private List resultLabel = new ArrayList<>();
49 | private yolov3Tiny yolov3tiny = new yolov3Tiny();
50 |
51 | @Override
52 | public void onCreate(Bundle savedInstanceState) {
53 | super.onCreate(savedInstanceState);
54 | setContentView(R.layout.activity_main);
55 | try {
56 | initYolov3Tiny();
57 | } catch (IOException e) {
58 | Log.e(TAG, "initYolov3Tiny error");
59 | }
60 | initView();
61 | readCacheLabelFromLocalFile();
62 | }
63 |
64 | //get assets file path
65 | private String getPathFromAssets(String assetsFileName){
66 | File f = new File(getCacheDir()+"/"+assetsFileName);
67 | //if (!f.exists())
68 | try {
69 | InputStream is = getAssets().open(assetsFileName);
70 | int size = is.available();
71 | byte[] buffer = new byte[size];
72 | is.read(buffer);
73 | is.close();
74 | FileOutputStream fos = new FileOutputStream(f);
75 | fos.write(buffer);
76 | fos.close();
77 | } catch (Exception e) { throw new RuntimeException(e); }
78 | return f.getPath();
79 | }
80 |
81 | private void initYolov3Tiny() throws IOException {
82 | // byte[] param = null;
83 | // byte[] bin = null;
84 | // {
85 | // InputStream assetsInputStream = getAssets().open("yolov3-tiny.param.bin");
86 | // int available = assetsInputStream.available();
87 | // param = new byte[available];
88 | // int byteCode = assetsInputStream.read(param);
89 | // assetsInputStream.close();
90 | // }
91 | // {
92 | // InputStream assetsInputStream = getAssets().open("yolov3-tiny.bin");
93 | // int available = assetsInputStream.available();
94 | // bin = new byte[available];
95 | // int byteCode = assetsInputStream.read(bin);
96 | // assetsInputStream.close();
97 | // }
98 |
99 | String paramPath=getPathFromAssets("yolov3-tiny.param");
100 | String binPath=getPathFromAssets("yolov3-tiny.bin");
101 |
102 | load_result = yolov3tiny.Init(paramPath, binPath);
103 | Log.d(TAG, "yolov3tiny_load_model_result:" + load_result);
104 | }
105 |
106 | // initialize view
107 | private void initView() {
108 | request_permissions();
109 | show_image = (ImageView) findViewById(R.id.show_image);
110 | result_text = (TextView) findViewById(R.id.result_text);
111 | result_text.setMovementMethod(ScrollingMovementMethod.getInstance());
112 | Button use_photo = (Button) findViewById(R.id.use_photo);
113 | // use photo click
114 | use_photo.setOnClickListener(new View.OnClickListener() {
115 | @Override
116 | public void onClick(View view) {
117 | if (!load_result) {
118 | Toast.makeText(MainActivity.this, "never load model", Toast.LENGTH_SHORT).show();
119 | return;
120 | }
121 | PhotoUtil.use_photo(MainActivity.this, SELECT_IMAGE);
122 | }
123 | });
124 | }
125 |
126 | // load label's name
127 | private void readCacheLabelFromLocalFile() {
128 | try {
129 | AssetManager assetManager = getApplicationContext().getAssets();
130 | BufferedReader reader = new BufferedReader(new InputStreamReader(assetManager.open("coco.names")));
131 | String readLine = null;
132 | while ((readLine = reader.readLine()) != null) {
133 | resultLabel.add(readLine);
134 | }
135 | reader.close();
136 | } catch (Exception e) {
137 | Log.e("labelCache", "error " + e);
138 | }
139 | }
140 |
141 | @Override
142 | protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
143 | String image_path;
144 | RequestOptions options = new RequestOptions().skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE);
145 | if (resultCode == Activity.RESULT_OK) {
146 | switch (requestCode) {
147 | case SELECT_IMAGE:
148 | if (data == null) {
149 | Log.w(TAG, "user photo data is null");
150 | return;
151 | }
152 | Uri image_uri = data.getData();
153 |
154 | //Glide.with(MainActivity.this).load(image_uri).apply(options).into(show_image);
155 |
156 | // get image path from uri
157 | image_path = PhotoUtil.get_path_from_URI(MainActivity.this, image_uri);
158 | // predict image
159 | predict_image(image_path);
160 | break;
161 | }
162 | }
163 | }
164 |
165 | // predict image
166 | private void predict_image(String image_path) {
167 | // picture to float array
168 | Bitmap bmp = PhotoUtil.getScaleBitmap(image_path);
169 | Bitmap rgba = bmp.copy(Bitmap.Config.ARGB_8888, true);
170 | // resize to 416x416
171 | Bitmap input_bmp = Bitmap.createScaledBitmap(rgba, ddims[2], ddims[3], false);
172 | try {
173 | // Data format conversion takes too long
174 | // Log.d("inputData", Arrays.toString(inputData));
175 | long start = System.currentTimeMillis();
176 | // get predict result
177 | float[] result = yolov3tiny.Detect(input_bmp);
178 | if ( result==null ) {
179 | result_text.setText("predict result is null");
180 | Log.d(TAG, " predict result is null");
181 | show_image.setImageBitmap(input_bmp);
182 | return;
183 | }
184 | long end = System.currentTimeMillis();
185 | Log.d(TAG, "origin predict result:" + Arrays.toString(result));
186 | long time = end - start;
187 | Log.d("result length", "length of result: " + String.valueOf(result.length));
188 | // show predict result and time
189 | //float[] r = get_max_result(result);
190 |
191 | String show_text = "time:" + time + "ms\n\n" ;
192 | Canvas canvas = new Canvas(input_bmp);
193 | //图像上画矩形
194 | Paint paint = new Paint();
195 |
196 | float finalResult[][] = convertArray(result);
197 | int object_num = result.length/6;// number of object
198 | //continue to draw rect
199 | for(int index = 0; index < object_num; index++){
200 | // 画框
201 | paint.setColor(Color.RED);
202 | paint.setStyle(Paint.Style.STROKE);//不填充
203 | paint.setStrokeWidth(2); //线的宽度
204 | canvas.drawRect(finalResult[index][2] * input_bmp.getWidth(), finalResult[index][3] * input_bmp.getHeight(),
205 | finalResult[index][4] * input_bmp.getWidth(), finalResult[index][5] * input_bmp.getHeight(), paint);
206 |
207 | //prob
208 | paint.setColor(Color.YELLOW);
209 | paint.setStyle(Paint.Style.FILL);
210 | paint.setStrokeWidth(4); //线的宽度
211 | String text = resultLabel.get((int) finalResult[index][0]) + " " + finalResult[index][1];
212 | canvas.drawText(text,
213 | finalResult[index][2]*input_bmp.getWidth(),finalResult[index][3]*input_bmp.getHeight(),paint);
214 | show_text+=text+"\n";
215 | }
216 | show_image.setImageBitmap(input_bmp);
217 | result_text.setText(show_text);
218 |
219 | } catch (Exception e) {
220 | e.printStackTrace();
221 | }
222 | }
223 |
224 | //结果一维数组转化为二维数组
225 | public static float[][] convertArray(float[] inputfloat){
226 | int n = inputfloat.length;
227 | int num = inputfloat.length/6;
228 | float[][] outputfloat = new float[num][6];
229 | int k = 0;
230 | for(int i = 0; i < num ; i++)
231 | {
232 | int j = 0;
233 | while(j<6)
234 | {
235 | outputfloat[i][j] = inputfloat[k];
236 | k++;
237 | j++;
238 | }
239 | }
240 | return outputfloat;
241 | }
242 |
243 |
244 | // get max probability label
245 | private float[] get_max_result(float[] result) {
246 | int num_rs = result.length / 6;
247 | float maxProp = result[1];
248 | int maxI = 0;
249 | for(int i = 1; i permissionList = new ArrayList<>();
265 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
266 | permissionList.add(Manifest.permission.CAMERA);
267 | }
268 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
269 | permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
270 | }
271 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
272 | permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
273 | }
274 | // if list is not empty will request permissions
275 | if (!permissionList.isEmpty()) {
276 | ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), 1);
277 | }
278 | }
279 |
280 | @Override
281 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
282 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
283 | switch (requestCode) {
284 | case 1:
285 | if (grantResults.length > 0) {
286 | for (int i = 0; i < grantResults.length; i++) {
287 | int grantResult = grantResults[i];
288 | if (grantResult == PackageManager.PERMISSION_DENIED) {
289 | String s = permissions[i];
290 | Toast.makeText(this, s + "permission was denied", Toast.LENGTH_SHORT).show();
291 | }
292 | }
293 | }
294 | break;
295 | }
296 | }
297 |
298 | }
299 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/yolov3tiny/PhotoUtil.java:
--------------------------------------------------------------------------------
1 | package com.example.yolov3tiny;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.database.Cursor;
7 | import android.graphics.Bitmap;
8 | import android.graphics.BitmapFactory;
9 | import android.net.Uri;
10 | import android.provider.MediaStore;
11 |
12 | public class PhotoUtil {
13 | // get picture in photo
14 | public static void use_photo(Activity activity, int requestCode) {
15 | Intent intent = new Intent(Intent.ACTION_PICK);
16 | intent.setType("image/*");
17 | activity.startActivityForResult(intent, requestCode);
18 | }
19 |
20 | // get photo from Uri
21 | public static String get_path_from_URI(Context context, Uri uri) {
22 | String result;
23 | Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
24 | if (cursor == null) {
25 | result = uri.getPath();
26 | } else {
27 | cursor.moveToFirst();
28 | int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
29 | result = cursor.getString(idx);
30 | cursor.close();
31 | }
32 | return result;
33 | }
34 |
35 | // compress picture
36 | public static Bitmap getScaleBitmap(String filePath) {
37 | BitmapFactory.Options opt = new BitmapFactory.Options();
38 | opt.inJustDecodeBounds = true;
39 | BitmapFactory.decodeFile(filePath, opt);
40 |
41 | int bmpWidth = opt.outWidth;
42 | int bmpHeight = opt.outHeight;
43 |
44 | int maxSize = 1280;//500
45 |
46 | // compress picture with inSampleSize
47 | opt.inSampleSize = 1;
48 | while (true) {
49 | if (bmpWidth / opt.inSampleSize < maxSize || bmpHeight / opt.inSampleSize < maxSize) {
50 | break;
51 | }
52 | opt.inSampleSize *= 2;
53 | }
54 | opt.inJustDecodeBounds = false;
55 | return BitmapFactory.decodeFile(filePath, opt);
56 | }
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/yolov3tiny/yolov3Tiny.java:
--------------------------------------------------------------------------------
1 | package com.example.yolov3tiny;
2 | import android.graphics.Bitmap;
3 |
4 | public class yolov3Tiny {
5 | public native boolean Init(String param, String bin);
6 | public native float[] Detect(Bitmap bitmap);
7 | static {
8 | System.loadLibrary("yolov3_tiny_jni");
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi-v7a/libncnn.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/jniLibs/armeabi-v7a/libncnn.a
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
14 |
20 |
21 |
28 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | yolov3-tiny-ncnn
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/tarmac/yolov2Tiny/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.tarmac.yolov2Tiny;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.4.1'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1024m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jun 26 08:34:47 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleomoon/darknet-ncnn-android/dea4cc0b128eb5054ff3f69af20d473f874558d2/screenshot.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------