mirror of
https://github.com/Tencent/ncnn.git
synced 2026-10-17 04:41:47 +08:00
add test python vulkan (#2754)
* add test python vulkan * add python vulkan ci on linux with 3.6 and 3.8 * fix ci vulkan icd
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
name: linux-x64-gpu-clang-python
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
linux-clang-gpu:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.8]
|
||||
steps:
|
||||
- name: cancel-previous-runs
|
||||
uses: styfle/cancel-workflow-action@0.7.0
|
||||
with:
|
||||
access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: update
|
||||
run: sudo apt-get update
|
||||
- name: protobuf
|
||||
run: sudo apt-get install libprotobuf-dev protobuf-compiler libopencv-dev
|
||||
- name: cache-vulkansdk
|
||||
id: cache-vulkansdk
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: "1.2.148.1"
|
||||
key: vulkansdk-linux-x86_64-1.2.148.1
|
||||
- name: vulkansdk
|
||||
if: steps.cache-vulkansdk.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
wget https://sdk.lunarg.com/sdk/download/1.2.148.1/linux/vulkansdk-linux-x86_64-1.2.148.1.tar.gz?Human=true -O vulkansdk-linux-x86_64-1.2.148.1.tar.gz
|
||||
tar -xf vulkansdk-linux-x86_64-1.2.148.1.tar.gz
|
||||
rm -rf 1.2.148.1/source 1.2.148.1/samples
|
||||
find 1.2.148.1 -type f | grep -v -E 'vulkan|glslang' | xargs rm
|
||||
- name: cache-swiftshader
|
||||
id: cache-swiftshader
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: swiftshader-install
|
||||
key: swiftshader-linux-install-20200508
|
||||
- name: checkout-swiftshader
|
||||
if: steps.cache-swiftshader.outputs.cache-hit != 'true'
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: google/swiftshader
|
||||
path: swiftshader
|
||||
ref: 2dd864470e310d173d35fa95ca3a14d216734aab
|
||||
- name: checkout-swiftshader-submodules
|
||||
if: steps.cache-swiftshader.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd swiftshader
|
||||
git submodule update --init --recursive
|
||||
- name: swiftshader
|
||||
if: steps.cache-swiftshader.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd swiftshader
|
||||
mkdir -p build; cd build
|
||||
cmake -DCMAKE_INSTALL_PREFIX=install -DSWIFTSHADER_BUILD_EGL=FALSE -DSWIFTSHADER_BUILD_GLESv2=FALSE -DSWIFTSHADER_BUILD_GLES_CM=FALSE -DSWIFTSHADER_BUILD_VULKAN=TRUE -DSWIFTSHADER_BUILD_PVR=FALSE -DSWIFTSHADER_BUILD_TESTS=FALSE -DSWIFTSHADER_ENABLE_ASTC=FALSE -DSWIFTSHADER_WARNINGS_AS_ERRORS=FALSE -DREACTOR_BACKEND=Subzero -DREACTOR_DEFAULT_OPT_LEVEL=Default -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build . -j 2
|
||||
mkdir $GITHUB_WORKSPACE/swiftshader-install
|
||||
cp Linux/* $GITHUB_WORKSPACE/swiftshader-install
|
||||
- name: set up python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pytest setuptools wheel twine
|
||||
- name: build
|
||||
env:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
run: |
|
||||
export VULKAN_SDK=`pwd`/1.2.148.1/x86_64
|
||||
mkdir build && cd build
|
||||
cmake -DNCNN_VULKAN=ON -DNCNN_PYTHON=ON ..
|
||||
cmake --build . -j 2
|
||||
- name: install python
|
||||
run: cd python && pip install .
|
||||
- name: test
|
||||
run: |
|
||||
export VK_ICD_FILENAMES="$GITHUB_WORKSPACE/swiftshader-install/vk_swiftshader_icd.json"
|
||||
cd python && pytest tests
|
||||
- name: build and publish
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
TWINE_REPOSITORY_URL: "https://test.pypi.org/legacy/"
|
||||
run: |
|
||||
cd python
|
||||
python setup.py bdist_wheel
|
||||
twine upload dist/*
|
||||
+38
-11
@@ -834,7 +834,7 @@ PYBIND11_MODULE(ncnn, m)
|
||||
#if NCNN_VULKAN
|
||||
.def("set_vulkan_device", (void (Net::*)(int)) & Net::set_vulkan_device, py::arg("device_index"))
|
||||
.def("set_vulkan_device", (void (Net::*)(const VulkanDevice*)) & Net::set_vulkan_device, py::arg("vkdev"))
|
||||
.def("vulkan_device", &Net::vulkan_device)
|
||||
.def("vulkan_device", &Net::vulkan_device, py::return_value_policy::reference_internal)
|
||||
#endif // NCNN_VULKAN
|
||||
|
||||
#if NCNN_STRING
|
||||
@@ -1116,8 +1116,19 @@ PYBIND11_MODULE(ncnn, m)
|
||||
m.def("get_gpu_info", &get_gpu_info, py::arg("device_index") = 0, py::return_value_policy::reference_internal);
|
||||
m.def("get_gpu_device", &get_gpu_device, py::arg("device_index") = 0, py::return_value_policy::reference_internal);
|
||||
|
||||
py::class_<VkBufferMemory>(m, "VkBufferMemory")
|
||||
.def_readwrite("offset", &VkBufferMemory::offset)
|
||||
.def_readwrite("capacity", &VkBufferMemory::capacity)
|
||||
.def_readwrite("refcount", &VkBufferMemory::refcount);
|
||||
|
||||
py::class_<VkImageMemory>(m, "VkImageMemory")
|
||||
.def_readwrite("width", &VkImageMemory::width)
|
||||
.def_readwrite("height", &VkImageMemory::height)
|
||||
.def_readwrite("depth", &VkImageMemory::depth)
|
||||
.def_readwrite("refcount", &VkImageMemory::refcount);
|
||||
|
||||
py::class_<VkAllocator, PyVkAllocator<> >(m, "VkAllocator")
|
||||
.def_readwrite("vkdev", &VkAllocator::vkdev)
|
||||
.def_readonly("vkdev", &VkAllocator::vkdev)
|
||||
.def_readwrite("buffer_memory_type_index", &VkAllocator::buffer_memory_type_index)
|
||||
.def_readwrite("image_memory_type_index", &VkAllocator::image_memory_type_index)
|
||||
.def_readwrite("mappable", &VkAllocator::mappable)
|
||||
@@ -1126,37 +1137,53 @@ PYBIND11_MODULE(ncnn, m)
|
||||
py::class_<VkBlobAllocator, VkAllocator, PyVkAllocatorOther<VkBlobAllocator> >(m, "VkBlobAllocator")
|
||||
.def(py::init<const VulkanDevice*>())
|
||||
.def("clear", &VkBlobAllocator::clear)
|
||||
.def("fastMalloc", (VkBufferMemory * (VkBlobAllocator::*)(size_t size)) & VkBlobAllocator::fastMalloc)
|
||||
.def("fastMalloc", (VkBufferMemory * (VkBlobAllocator::*)(size_t size)) & VkBlobAllocator::fastMalloc, py::return_value_policy::reference_internal)
|
||||
.def("fastFree", (void (VkBlobAllocator::*)(VkBufferMemory * ptr)) & VkBlobAllocator::fastFree)
|
||||
.def("fastMalloc", (VkImageMemory * (VkBlobAllocator::*)(int, int, int, size_t, int)) & VkBlobAllocator::fastMalloc)
|
||||
.def("fastMalloc", (VkImageMemory * (VkBlobAllocator::*)(int, int, int, size_t, int)) & VkBlobAllocator::fastMalloc, py::return_value_policy::reference_internal)
|
||||
.def("fastFree", (void (VkBlobAllocator::*)(VkImageMemory * ptr)) & VkBlobAllocator::fastFree);
|
||||
|
||||
py::class_<VkWeightAllocator, VkAllocator, PyVkAllocatorOther<VkWeightAllocator> >(m, "VkWeightAllocator")
|
||||
.def(py::init<const VulkanDevice*>())
|
||||
.def("clear", &VkWeightAllocator::clear)
|
||||
.def("fastMalloc", (VkBufferMemory * (VkWeightAllocator::*)(size_t size)) & VkWeightAllocator::fastMalloc)
|
||||
.def("fastMalloc", (VkBufferMemory * (VkWeightAllocator::*)(size_t size)) & VkWeightAllocator::fastMalloc, py::return_value_policy::reference_internal)
|
||||
.def("fastFree", (void (VkWeightAllocator::*)(VkBufferMemory * ptr)) & VkWeightAllocator::fastFree)
|
||||
.def("fastMalloc", (VkImageMemory * (VkWeightAllocator::*)(int, int, int, size_t, int)) & VkWeightAllocator::fastMalloc)
|
||||
.def("fastMalloc", (VkImageMemory * (VkWeightAllocator::*)(int, int, int, size_t, int)) & VkWeightAllocator::fastMalloc, py::return_value_policy::reference_internal)
|
||||
.def("fastFree", (void (VkWeightAllocator::*)(VkImageMemory * ptr)) & VkWeightAllocator::fastFree);
|
||||
|
||||
py::class_<VkStagingAllocator, VkAllocator, PyVkAllocatorOther<VkStagingAllocator> >(m, "VkStagingAllocator")
|
||||
.def(py::init<const VulkanDevice*>())
|
||||
.def("set_size_compare_ratio", &VkStagingAllocator::set_size_compare_ratio)
|
||||
.def("clear", &VkStagingAllocator::clear)
|
||||
.def("fastMalloc", (VkBufferMemory * (VkStagingAllocator::*)(size_t size)) & VkStagingAllocator::fastMalloc)
|
||||
.def("fastMalloc", (VkBufferMemory * (VkStagingAllocator::*)(size_t size)) & VkStagingAllocator::fastMalloc, py::return_value_policy::reference_internal)
|
||||
.def("fastFree", (void (VkStagingAllocator::*)(VkBufferMemory * ptr)) & VkStagingAllocator::fastFree)
|
||||
.def("fastMalloc", (VkImageMemory * (VkStagingAllocator::*)(int, int, int, size_t, int)) & VkStagingAllocator::fastMalloc)
|
||||
.def("fastMalloc", (VkImageMemory * (VkStagingAllocator::*)(int, int, int, size_t, int)) & VkStagingAllocator::fastMalloc, py::return_value_policy::reference_internal)
|
||||
.def("fastFree", (void (VkStagingAllocator::*)(VkImageMemory * ptr)) & VkStagingAllocator::fastFree);
|
||||
|
||||
py::class_<VkWeightStagingAllocator, VkAllocator, PyVkAllocatorOther<VkWeightStagingAllocator> >(m, "VkWeightStagingAllocator")
|
||||
.def(py::init<const VulkanDevice*>())
|
||||
.def("fastMalloc", (VkBufferMemory * (VkWeightStagingAllocator::*)(size_t size)) & VkWeightStagingAllocator::fastMalloc)
|
||||
.def("fastMalloc", (VkBufferMemory * (VkWeightStagingAllocator::*)(size_t size)) & VkWeightStagingAllocator::fastMalloc, py::return_value_policy::reference_internal)
|
||||
.def("fastFree", (void (VkWeightStagingAllocator::*)(VkBufferMemory * ptr)) & VkWeightStagingAllocator::fastFree)
|
||||
.def("fastMalloc", (VkImageMemory * (VkWeightStagingAllocator::*)(int, int, int, size_t, int)) & VkWeightStagingAllocator::fastMalloc)
|
||||
.def("fastMalloc", (VkImageMemory * (VkWeightStagingAllocator::*)(int, int, int, size_t, int)) & VkWeightStagingAllocator::fastMalloc, py::return_value_policy::reference_internal)
|
||||
.def("fastFree", (void (VkWeightStagingAllocator::*)(VkImageMemory * ptr)) & VkWeightStagingAllocator::fastFree);
|
||||
|
||||
py::class_<GpuInfo>(m, "GpuInfo")
|
||||
.def(py::init<>())
|
||||
.def("api_version", &GpuInfo::api_version)
|
||||
.def("driver_version", &GpuInfo::driver_version)
|
||||
.def("vendor_id", &GpuInfo::vendor_id)
|
||||
.def("device_id", &GpuInfo::device_id)
|
||||
.def("pipeline_cache_uuid", [](GpuInfo& gpuinfo) {
|
||||
return py::memoryview::from_buffer(gpuinfo.pipeline_cache_uuid(), {VK_UUID_SIZE}, {sizeof(uint8_t) * VK_UUID_SIZE});
|
||||
})
|
||||
.def("type", &GpuInfo::type);
|
||||
|
||||
py::class_<VulkanDevice>(m, "VulkanDevice")
|
||||
.def(py::init<int>(), py::arg("device_index") = 0);
|
||||
.def(py::init<int>(), py::arg("device_index") = 0)
|
||||
.def(
|
||||
"info", [](VulkanDevice& dev) {
|
||||
return &dev.info;
|
||||
},
|
||||
py::return_value_policy::reference_internal);
|
||||
#endif // NCNN_VULKAN
|
||||
|
||||
m.doc() = R"pbdoc(
|
||||
|
||||
@@ -38,6 +38,34 @@ def test_net():
|
||||
assert len(net.blobs()) == 0 and len(net.layers()) == 0
|
||||
|
||||
|
||||
def test_net_vulkan():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
dr = ncnn.DataReaderFromEmpty()
|
||||
|
||||
net = ncnn.Net()
|
||||
net.opt.use_vulkan_compute = True
|
||||
ret = net.load_param("tests/test.param")
|
||||
net.load_model(dr)
|
||||
assert ret == 0 and len(net.blobs()) == 3 and len(net.layers()) == 3
|
||||
|
||||
in_mat = ncnn.Mat((227, 227, 3))
|
||||
|
||||
ex = net.create_extractor()
|
||||
ex.input("data", in_mat)
|
||||
ret, out_mat = ex.extract("output")
|
||||
|
||||
assert ret == 0 and out_mat.dims == 1 and out_mat.w == 1
|
||||
|
||||
net.clear()
|
||||
assert len(net.blobs()) == 0 and len(net.layers()) == 0
|
||||
|
||||
# ensure ex release before net when use vulkan
|
||||
ex = None
|
||||
net = None
|
||||
|
||||
|
||||
def test_custom_layer():
|
||||
class CustomLayer(ncnn.Layer):
|
||||
customLayers = []
|
||||
@@ -89,3 +117,26 @@ def test_custom_layer():
|
||||
|
||||
net.clear()
|
||||
assert len(net.blobs()) == 0 and len(net.layers()) == 0
|
||||
|
||||
|
||||
def test_vulkan_device_index():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
net = ncnn.Net()
|
||||
assert net.vulkan_device() is None
|
||||
|
||||
net.set_vulkan_device(0)
|
||||
assert net.vulkan_device() is not None
|
||||
|
||||
|
||||
def test_vulkan_device_vkdev():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
net = ncnn.Net()
|
||||
assert net.vulkan_device() is None
|
||||
|
||||
vkdev = ncnn.get_gpu_device(0)
|
||||
net.set_vulkan_device(vkdev)
|
||||
assert net.vulkan_device() is not None
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
# Tencent is pleased to support the open source community by making ncnn available.
|
||||
#
|
||||
# Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
#
|
||||
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
# in compliance with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
import pytest
|
||||
|
||||
import ncnn
|
||||
|
||||
|
||||
def test_vk_blob_allocator():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
vkdev = ncnn.get_gpu_device(0)
|
||||
assert vkdev is not None
|
||||
allocator = ncnn.VkBlobAllocator(vkdev)
|
||||
assert allocator.buffer_memory_type_index >= 0
|
||||
assert allocator.image_memory_type_index >= 0
|
||||
|
||||
mappable = allocator.mappable
|
||||
allocator.mappable = not mappable
|
||||
assert allocator.mappable == (not mappable)
|
||||
|
||||
coherent = allocator.coherent
|
||||
allocator.coherent = not coherent
|
||||
assert allocator.coherent == (not coherent)
|
||||
|
||||
bufmem = allocator.fastMalloc(10 * 1024)
|
||||
assert bufmem is not None
|
||||
allocator.fastFree(bufmem)
|
||||
|
||||
imgmem = allocator.fastMalloc(4, 4, 3, 4, 1)
|
||||
assert imgmem is not None
|
||||
allocator.fastFree(imgmem)
|
||||
|
||||
|
||||
def test_vk_weight_allocator():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
vkdev = ncnn.get_gpu_device(0)
|
||||
assert vkdev is not None
|
||||
allocator = ncnn.VkWeightAllocator(vkdev)
|
||||
assert allocator.buffer_memory_type_index >= 0
|
||||
assert allocator.image_memory_type_index >= 0
|
||||
|
||||
mappable = allocator.mappable
|
||||
allocator.mappable = not mappable
|
||||
assert allocator.mappable == (not mappable)
|
||||
|
||||
coherent = allocator.coherent
|
||||
allocator.coherent = not coherent
|
||||
assert allocator.coherent == (not coherent)
|
||||
|
||||
bufmem = allocator.fastMalloc(10 * 1024)
|
||||
assert bufmem is not None
|
||||
allocator.fastFree(bufmem)
|
||||
|
||||
imgmem = allocator.fastMalloc(4, 4, 3, 4, 1)
|
||||
assert imgmem is not None
|
||||
allocator.fastFree(imgmem)
|
||||
|
||||
|
||||
def test_vk_staging_allocator():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
vkdev = ncnn.get_gpu_device(0)
|
||||
assert vkdev is not None
|
||||
allocator = ncnn.VkStagingAllocator(vkdev)
|
||||
assert allocator.buffer_memory_type_index >= 0
|
||||
assert allocator.image_memory_type_index >= 0
|
||||
|
||||
mappable = allocator.mappable
|
||||
allocator.mappable = not mappable
|
||||
assert allocator.mappable == (not mappable)
|
||||
|
||||
coherent = allocator.coherent
|
||||
allocator.coherent = not coherent
|
||||
assert allocator.coherent == (not coherent)
|
||||
|
||||
bufmem = allocator.fastMalloc(10 * 1024)
|
||||
assert bufmem is not None
|
||||
allocator.fastFree(bufmem)
|
||||
|
||||
imgmem = allocator.fastMalloc(4, 4, 3, 4, 1)
|
||||
assert imgmem is not None
|
||||
allocator.fastFree(imgmem)
|
||||
|
||||
|
||||
def test_vk_weight_staging_allocator():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
vkdev = ncnn.get_gpu_device(0)
|
||||
assert vkdev is not None
|
||||
allocator = ncnn.VkWeightStagingAllocator(vkdev)
|
||||
assert allocator.buffer_memory_type_index >= 0
|
||||
assert allocator.image_memory_type_index >= 0
|
||||
|
||||
mappable = allocator.mappable
|
||||
allocator.mappable = not mappable
|
||||
assert allocator.mappable == (not mappable)
|
||||
|
||||
coherent = allocator.coherent
|
||||
allocator.coherent = not coherent
|
||||
assert allocator.coherent == (not coherent)
|
||||
|
||||
bufmem = allocator.fastMalloc(10 * 1024)
|
||||
assert bufmem is not None
|
||||
allocator.fastFree(bufmem)
|
||||
|
||||
imgmem = allocator.fastMalloc(4, 4, 3, 4, 1)
|
||||
assert imgmem is None
|
||||
@@ -0,0 +1,55 @@
|
||||
# Tencent is pleased to support the open source community by making ncnn available.
|
||||
#
|
||||
# Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
#
|
||||
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
# in compliance with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
import pytest
|
||||
|
||||
import ncnn
|
||||
|
||||
|
||||
def check_gpuinfo(gpuinfo):
|
||||
assert gpuinfo.api_version() > 0
|
||||
assert gpuinfo.driver_version() > 0
|
||||
assert gpuinfo.vendor_id() > 0
|
||||
assert gpuinfo.device_id() > 0
|
||||
assert gpuinfo.pipeline_cache_uuid() is not None
|
||||
assert gpuinfo.type() >= 0
|
||||
|
||||
|
||||
def test_gpu_api():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
assert ncnn.create_gpu_instance() == 0
|
||||
assert ncnn.get_gpu_count() > 0
|
||||
assert ncnn.get_default_gpu_index() >= 0
|
||||
|
||||
gpuinfo = ncnn.get_gpu_info(0)
|
||||
check_gpuinfo(gpuinfo)
|
||||
|
||||
vkdev = ncnn.get_gpu_device(0)
|
||||
assert vkdev is not None
|
||||
gpuinfo = vkdev.info()
|
||||
check_gpuinfo(gpuinfo)
|
||||
|
||||
ncnn.destroy_gpu_instance()
|
||||
|
||||
|
||||
def test_vulkan_device():
|
||||
if not hasattr(ncnn, "get_gpu_count"):
|
||||
return
|
||||
|
||||
vkdev = ncnn.VulkanDevice(0)
|
||||
assert vkdev is not None
|
||||
gpuinfo = vkdev.info()
|
||||
check_gpuinfo(gpuinfo)
|
||||
Reference in New Issue
Block a user