PeriDyno 1.0.0
Loading...
Searching...
No Matches
VkSort.inl
Go to the documentation of this file.
1
2#include "VkTransfer.h"
3
4namespace dyno {
5
6 inline int ComputeAddZeroSize(int OriginalSize) {
7 int AddZeroSize = 2;
8 while (AddZeroSize < OriginalSize) {
9 AddZeroSize *= 2;
10 }
11
12 return AddZeroSize;
13 }
14
15 template<typename T>
16 void VkSort<T>::sort(std::vector<T> &data, uint32_t SortType) {
17 uint32_t dSize = data.size();
18
19 VkDeviceArray<T> kArray;
20 kArray.resize(data.size());
21 vkTransfer(kArray, data);
22
23 // sort dArray into a non-descending order
24 sort(kArray, SortType);
25
26 std::vector<T> ouputData(data.size());
27 vkTransfer(ouputData, kArray);
28
29 data.swap(ouputData);
30 };
31
32
33
34
35 template<typename T>
36 void VkSort<T>::sort(VkDeviceArray<T>& data, uint32_t SortType)
37 {
38 int AddZeroSize = ComputeAddZeroSize(data.size());
39 uint32_t globalSize = AddZeroSize;
40
41 uint32_t workgroup_size_x;
42
43 if (AddZeroSize < 128) {
44 workgroup_size_x = AddZeroSize / 2;
45 }
46 else {
47 workgroup_size_x = 64;
48 }
49
50 VkUniform<Parameters> uniformParam;
51
52 VkDeviceArray<T> AddZeroArray;
53 AddZeroArray.resize(AddZeroSize);
54
55 const uint32_t workgroup_count = globalSize / (workgroup_size_x * 2);
56
57 uint32_t h = workgroup_size_x * 2;
58
59 dim3 groupSize;
60 groupSize.x = workgroup_count;
61
62 Parameters param;
63
64 // SortType UP 0/ DOWN 1
65 param.SortType = SortType;
66 param.srcSize = AddZeroArray.size();
67 param.dstSize = data.size();
68 //AddZeroArray: add 0 elements to data array
69 param.h = data.size();
71 uniformParam.setValue(param);
72 mSortKernel->flush(groupSize, &data, &uniformParam, &AddZeroArray);
73
74 //TODO: replace flush with enqueue
75 param.h = h;
77 uniformParam.setValue(param);
78 mSortKernel->flush(groupSize, &AddZeroArray, &uniformParam, &data);
79
80 // we must now double h, as this happens before every flip
81 h *= 2;
82
83 for (; h <= globalSize; h *= 2) {
84
85 param.h = h;
86 param.srcSize = data.size();
87 param.dstSize = AddZeroArray.size();
88 //param.n = globalSize;
90 uniformParam.setValue(param);
91 mSortKernel->flush(groupSize, &AddZeroArray, &uniformParam, &data);
92
93 for (uint32_t hh = h / 2; hh > 1; hh /= 2) {
94 if (hh <= workgroup_size_x * 2) {
95 param.h = hh;
96 //param.n = globalSize;
98 uniformParam.setValue(param);
99 mSortKernel->flush(groupSize, &AddZeroArray, &uniformParam, &data);
100 break;
101 }
102 else {
103 param.h = hh;
104 //param.n = globalSize;
106 uniformParam.setValue(param);
107 mSortKernel->flush(groupSize, &AddZeroArray, &uniformParam, &data);
108 }
109 }
110 }
111
112 //data subtract zero element
113 param.h = h;
115 uniformParam.setValue(param);
116 mSortKernel->flush(groupSize, &data, &uniformParam, &AddZeroArray);
117 }
118
119 template<typename T>
120 void VkSort<T>::sort_by_key(std::vector<T>& keys, std::vector<T>& values, uint32_t SortType) {
121 assert(keys.size() == values.size());
122
123 uint32_t dSize = keys.size();
124
125 VkDeviceArray<T> kArray;
126 kArray.resize(keys.size());
127 vkTransfer(kArray, keys);
128
129 VkDeviceArray<T> vArray;
130 vArray.resize(values.size());
131 vkTransfer(vArray, values);
132
133 // sort dArray into a non-descending order
134 sort_by_key(kArray, vArray, SortType);
135
136 std::vector<T> ouputKData(keys.size());
137 vkTransfer(ouputKData, kArray);
138
139 std::vector<T> ouputVData(values.size());
140 vkTransfer(ouputVData, vArray);
141
142 keys.swap(ouputKData);
143 values.swap(ouputVData);
144 }
145
146
147
148 template<typename T>
149 void VkSort<T>::sort_by_key(VkDeviceArray<T>& keys, VkDeviceArray<T>& values, uint32_t SortType)
150 {
151 assert(keys.size() == values.size());
152 int AddZeroSize = ComputeAddZeroSize(keys.size());
153
154 uint32_t workgroup_size_x;
155 if (AddZeroSize < 128) {
156 workgroup_size_x = AddZeroSize / 2;
157 }
158 else {
159 workgroup_size_x = 64;
160 }
161
162 uint32_t globalSize = AddZeroSize;
163
164 VkUniform<Parameters> uniformParam;
165
166 VkDeviceArray<T> KeysAddZeroArray;
167 KeysAddZeroArray.resize(AddZeroSize);
168 VkDeviceArray<T> ValuesAddZeroArray;
169 ValuesAddZeroArray.resize(AddZeroSize);
170
171 const uint32_t workgroup_count = globalSize / (workgroup_size_x * 2);
172
173 uint32_t h = workgroup_size_x * 2;
174
175 dim3 groupSize;
176 groupSize.x = workgroup_count;
177
178 Parameters param;
179
180 // SortType UP 0/ DOWN 1
181 param.SortType = SortType;
182
183 //AddZeroArray: add 0 elements to data array
184 param.h = keys.size();
185 param.srcSize = KeysAddZeroArray.size();
186 param.dstSize = keys.size();
187 //param.h = h;
189 uniformParam.setValue(param);
190 mSortByKeyKernel->flush(groupSize, &keys, &values, &uniformParam, &KeysAddZeroArray, &ValuesAddZeroArray);
191
192 //TODO: replace flush with enqueue
193 param.h = h;
194 param.srcSize = keys.size();
195 param.dstSize = KeysAddZeroArray.size();
197 uniformParam.setValue(param);
198 mSortByKeyKernel->flush(groupSize, &KeysAddZeroArray, &ValuesAddZeroArray, &uniformParam, &keys, &values);
199
200 // we must now double h, as this happens before every flip
201 h *= 2;
202
203 //if the data is small, reduce the group
204
205 for (; h <= globalSize; h *= 2) {
206 param.h = h;
207 param.srcSize = keys.size();
208 param.dstSize = KeysAddZeroArray.size();
209 //param.n = globalSize;
211 uniformParam.setValue(param);
212 mSortByKeyKernel->flush(groupSize, &KeysAddZeroArray, &ValuesAddZeroArray, &uniformParam, &keys, &values);
213
214 for (uint32_t hh = h / 2; hh > 1; hh /= 2) {
215 if (hh <= workgroup_size_x * 2) {
216 param.h = hh;
217 //param.n = globalSize;
219 uniformParam.setValue(param);
220 mSortByKeyKernel->flush(groupSize, &KeysAddZeroArray, &ValuesAddZeroArray, &uniformParam, &keys, &values);
221 break;
222 }
223 else {
224 param.h = hh;
225 //param.n = globalSize;
227 uniformParam.setValue(param);
228 mSortByKeyKernel->flush(groupSize, &KeysAddZeroArray, &ValuesAddZeroArray, &uniformParam, &keys, &values);
229 }
230 }
231 }
232
233 //data subtract zero element
234 param.h = h;
235 param.srcSize = KeysAddZeroArray.size();
236 param.dstSize = keys.size();
238 uniformParam.setValue(param);
239 mSortByKeyKernel->flush(groupSize, &keys, &values, &uniformParam, &KeysAddZeroArray, &ValuesAddZeroArray);
240
241 KeysAddZeroArray.clear();
242 ValuesAddZeroArray.clear();
243 }
244
245 template<typename T>
247
248 mSortKernel = std::make_shared<VkProgram>(
249 BUFFER(T),
251 BUFFER(T));
252
253 mSortByKeyKernel = std::make_shared<VkProgram>(
254 BUFFER(T),
255 BUFFER(T),
257 BUFFER(T),
258 BUFFER(T));
259
260 mSortKernel->load(getDynamicSpvFile<T>("shaders/glsl/core/Sort.comp.spv"));
261 mSortByKeyKernel->load(getDynamicSpvFile<T>("shaders/glsl/core/SortByKey.comp.spv"));
262 }
263
264 template<typename T>
266 mSortKernel = nullptr;
267 mSortByKeyKernel = nullptr;
268 }
269}
#define UNIFORM(T)
Definition VkProgram.h:99
#define BUFFER(T)
Definition VkProgram.h:96
assert(queueCount >=1)
std::string getDynamicSpvFile(const std::string &fileName)
Definition VulkanTools.h:67
VkResizeType resize(uint32_t num, VkBufferUsageFlags usageFlags=0)
uint32_t size() const
std::shared_ptr< VkProgram > mSortByKeyKernel
Definition VkSort.h:46
void sort(std::vector< T > &data, uint32_t SortType)
Definition VkSort.inl:16
void sort_by_key(std::vector< T > &keys, std::vector< T > &values, uint32_t SortType)
Definition VkSort.inl:120
std::shared_ptr< VkProgram > mSortKernel
Definition VkSort.h:45
void setValue(T val)
Definition VkUniform.inl:32
#define T(t)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
int ComputeAddZeroSize(int OriginalSize)
Definition VkSort.inl:6
bool vkTransfer(VkHostArray< T > &dst, const VkDeviceArray< T > &src)
Definition VkTransfer.inl:7
implement functions for reorganizing ranges into sorted order
Definition VkSort.h:13
uint32_t dstSize
Definition VkSort.h:25
eAlgorithmVariant algorithm
Definition VkSort.h:26
uint32_t srcSize
Definition VkSort.h:24
uint32_t SortType
Definition VkSort.h:23
uint32_t h
Definition VkSort.h:22