1 // Tencent is pleased to support the open source community by making ncnn available.
2 //
3 // Copyright (C) 2021 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 #include "command.h"
16 #include "gpu.h"
17 #include "mat.h"
18 #include "testutil.h"
19 
test_command_upload_download(const ncnn::Mat & a)20 static int test_command_upload_download(const ncnn::Mat& a)
21 {
22     ncnn::VulkanDevice* vkdev = ncnn::get_gpu_device();
23 
24     ncnn::VkAllocator* blob_allocator = vkdev->acquire_blob_allocator();
25     ncnn::VkAllocator* staging_allocator = vkdev->acquire_staging_allocator();
26 
27     ncnn::Option opt;
28     opt.use_vulkan_compute = true;
29     opt.blob_vkallocator = blob_allocator;
30     opt.staging_vkallocator = staging_allocator;
31 
32     if (!vkdev->info.support_fp16_packed()) opt.use_fp16_packed = false;
33     if (!vkdev->info.support_fp16_storage()) opt.use_fp16_storage = false;
34 
35     ncnn::Mat d;
36     ncnn::Mat e;
37     {
38         ncnn::VkCompute cmd(vkdev);
39 
40         ncnn::VkMat b1;
41         ncnn::VkImageMat b2;
42         ncnn::VkImageMat c1;
43         ncnn::VkMat c2;
44         cmd.record_upload(a, b1, opt);
45         cmd.record_upload(a, c1, opt);
46         cmd.record_buffer_to_image(b1, b2, opt);
47         cmd.record_image_to_buffer(c1, c2, opt);
48         cmd.record_download(b2, d, opt);
49         cmd.record_download(c2, e, opt);
50 
51         cmd.submit_and_wait();
52     }
53 
54     vkdev->reclaim_blob_allocator(blob_allocator);
55     vkdev->reclaim_staging_allocator(staging_allocator);
56 
57     if (CompareMat(a, d, 0.001) != 0)
58     {
59         fprintf(stderr, "test_command_upload_download buffer failed a.dims=%d a=(%d %d %d)\n", a.dims, a.w, a.h, a.c);
60         return -1;
61     }
62 
63     if (CompareMat(a, e, 0.001) != 0)
64     {
65         fprintf(stderr, "test_command_upload_download image failed a.dims=%d a=(%d %d %d)\n", a.dims, a.w, a.h, a.c);
66         return -1;
67     }
68 
69     return 0;
70 }
71 
test_command_clone(const ncnn::Mat & a)72 static int test_command_clone(const ncnn::Mat& a)
73 {
74     ncnn::VulkanDevice* vkdev = ncnn::get_gpu_device();
75 
76     ncnn::VkAllocator* blob_allocator = vkdev->acquire_blob_allocator();
77     ncnn::VkAllocator* staging_allocator = vkdev->acquire_staging_allocator();
78 
79     ncnn::Option opt;
80     opt.use_vulkan_compute = true;
81     opt.blob_vkallocator = blob_allocator;
82     opt.staging_vkallocator = staging_allocator;
83 
84     if (!vkdev->info.support_fp16_packed()) opt.use_fp16_packed = false;
85     if (!vkdev->info.support_fp16_storage()) opt.use_fp16_storage = false;
86 
87     ncnn::Mat d;
88     ncnn::Mat e;
89     {
90         ncnn::VkCompute cmd(vkdev);
91 
92         ncnn::VkMat b1;
93         ncnn::VkMat b2;
94         ncnn::VkImageMat b3;
95         ncnn::VkImageMat c1;
96         ncnn::VkImageMat c2;
97         ncnn::VkMat c3;
98         cmd.record_clone(a, b1, opt);
99         cmd.record_clone(a, c1, opt);
100         cmd.record_clone(b1, b2, opt);
101         cmd.record_clone(c1, c2, opt);
102         cmd.record_clone(b2, b3, opt);
103         cmd.record_clone(c2, c3, opt);
104         cmd.record_clone(b3, d, opt);
105         cmd.record_clone(c3, e, opt);
106 
107         cmd.submit_and_wait();
108     }
109 
110     vkdev->reclaim_blob_allocator(blob_allocator);
111     vkdev->reclaim_staging_allocator(staging_allocator);
112 
113     if (CompareMat(a, d, 0.001) != 0)
114     {
115         fprintf(stderr, "test_command_clone buffer failed a.dims=%d a=(%d %d %d)\n", a.dims, a.w, a.h, a.c);
116         return -1;
117     }
118 
119     if (CompareMat(a, e, 0.001) != 0)
120     {
121         fprintf(stderr, "test_command_clone image failed a.dims=%d a=(%d %d %d)\n", a.dims, a.w, a.h, a.c);
122         return -1;
123     }
124 
125     return 0;
126 }
127 
test_command_transfer(const ncnn::Mat & a)128 static int test_command_transfer(const ncnn::Mat& a)
129 {
130     ncnn::VulkanDevice* vkdev = ncnn::get_gpu_device();
131 
132     ncnn::VkAllocator* blob_allocator = vkdev->acquire_blob_allocator();
133     ncnn::VkAllocator* staging_allocator = vkdev->acquire_staging_allocator();
134 
135     ncnn::Option opt;
136     opt.use_vulkan_compute = true;
137     opt.blob_vkallocator = blob_allocator;
138     opt.staging_vkallocator = staging_allocator;
139 
140     if (!vkdev->info.support_fp16_packed()) opt.use_fp16_packed = false;
141     if (!vkdev->info.support_fp16_storage()) opt.use_fp16_storage = false;
142 
143     ncnn::Mat d;
144     ncnn::Mat e;
145     {
146         ncnn::VkTransfer cmd1(vkdev);
147 
148         ncnn::VkMat b1;
149         ncnn::VkImageMat c1;
150         cmd1.record_upload(a, b1, opt, false);
151         cmd1.record_upload(a, c1, opt);
152 
153         cmd1.submit_and_wait();
154 
155         ncnn::VkCompute cmd2(vkdev);
156 
157         cmd2.record_download(b1, d, opt);
158         cmd2.record_download(c1, e, opt);
159 
160         cmd2.submit_and_wait();
161     }
162 
163     vkdev->reclaim_blob_allocator(blob_allocator);
164     vkdev->reclaim_staging_allocator(staging_allocator);
165 
166     if (CompareMat(a, d, 0.001) != 0)
167     {
168         fprintf(stderr, "test_command_transfer buffer failed a.dims=%d a=(%d %d %d)\n", a.dims, a.w, a.h, a.c);
169         return -1;
170     }
171 
172     if (CompareMat(a, e, 0.001) != 0)
173     {
174         fprintf(stderr, "test_command_transfer image failed a.dims=%d a=(%d %d %d)\n", a.dims, a.w, a.h, a.c);
175         return -1;
176     }
177 
178     return 0;
179 }
180 
test_command_0()181 static int test_command_0()
182 {
183     return 0
184            || test_command_upload_download(RandomMat(5, 7, 24))
185            || test_command_upload_download(RandomMat(7, 9, 12))
186            || test_command_upload_download(RandomMat(3, 5, 13))
187            || test_command_upload_download(RandomMat(15, 24))
188            || test_command_upload_download(RandomMat(19, 12))
189            || test_command_upload_download(RandomMat(17, 15))
190            || test_command_upload_download(RandomMat(128))
191            || test_command_upload_download(RandomMat(124))
192            || test_command_upload_download(RandomMat(127));
193 }
194 
test_command_1()195 static int test_command_1()
196 {
197     return 0
198            || test_command_clone(RandomMat(5, 7, 24))
199            || test_command_clone(RandomMat(7, 9, 12))
200            || test_command_clone(RandomMat(3, 5, 13))
201            || test_command_clone(RandomMat(15, 24))
202            || test_command_clone(RandomMat(19, 12))
203            || test_command_clone(RandomMat(17, 15))
204            || test_command_clone(RandomMat(128))
205            || test_command_clone(RandomMat(124))
206            || test_command_clone(RandomMat(127));
207 }
208 
test_command_2()209 static int test_command_2()
210 {
211     return 0
212            || test_command_transfer(RandomMat(5, 7, 24))
213            || test_command_transfer(RandomMat(7, 9, 12))
214            || test_command_transfer(RandomMat(3, 5, 13))
215            || test_command_transfer(RandomMat(15, 24))
216            || test_command_transfer(RandomMat(19, 12))
217            || test_command_transfer(RandomMat(17, 15))
218            || test_command_transfer(RandomMat(128))
219            || test_command_transfer(RandomMat(124))
220            || test_command_transfer(RandomMat(127));
221 }
222 
main()223 int main()
224 {
225     SRAND(7767517);
226 
227     return test_command_0() || test_command_1() || test_command_2();
228 }
229