@@ -34,7 +34,8 @@ struct ArbLatticeExecutor : public LinearExecutor {
3434
3535template <eOperationType I, eCalculateGlobals G, eStage S>
3636void ArbLatticeLauncher::RunBorder(CudaStream_t stream, const LatticeData& data) const {
37- const ArbLatticeExecutor<I, G, S> executor{{container.num_border_nodes}, container, data, 0};
37+ const ArbLatticeExecutor<I, G, S> executor{{container.num_border_nodes},
38+ container, data, 0};
3839 LaunchExecutorAsync(executor, stream);
3940}
4041
@@ -99,6 +100,7 @@ struct GetQuantityArbExecutor<?%s q$name?> : public LinearExecutor {
99100 LatticeData data;
100101 <?%s q$type ?>* buf;
101102 real_t scale;
103+ unsigned int offset; // Starting offset for iteration space
102104
103105 CudaDeviceFunction void Execute() const {
104106 using LA = ArbLatticeAccess; <?R
@@ -109,7 +111,8 @@ if (q$adjoint) { ?>
109111}?>
110112 const int i = threadID(CudaThread, CudaBlock, CudaNumberOfThreads);
111113 if (inRange(i)) {
112- LA acc(i, container);
114+ const int index = i + offset;
115+ LA acc(index, container);
113116 N now(acc, data);
114117 acc.pop(now); <?R
115118if (q$adjoint) { ?>
@@ -129,10 +132,68 @@ if (q$type == "vector_t") {
129132};
130133
131134void ArbLatticeLauncher::getQuantity<?%s q$name ?>(<?%s q$type ?>* tab, real_t scale, const LatticeData& data) const {
132- const GetQuantityArbExecutor<?%s q$name?> executor{{container.num_border_nodes + container.num_interior_nodes}, container, data, tab, scale};
135+ const GetQuantityArbExecutor<?%s q$name?> executor{{container.num_border_nodes + container.num_interior_nodes}, container, data, tab, scale, 0};
136+ LaunchExecutor(executor);
137+ }
138+
139+ void ArbLatticeLauncher::getSample<?%s q$name ?>(<?%s q$type ?>* tab, real_t scale, const LatticeData& data, unsigned int lid) const {
140+ const GetQuantityArbExecutor<?%s q$name?> executor{{1}, container, data, tab, scale, lid};
133141 LaunchExecutor(executor);
134142}
143+
135144<?R }
136145ifdef() ?>
137146
147+ struct CartesianCoordinateMapperArbExecutor: public LinearExecutor {
148+ ArbLatticeContainer container;
149+ LatticeData data;
150+ vector_t point; // cartesian point coordinates
151+ real_t epsilon2; // should be a small value (e.g. < 1e-10) to match with only one point
152+ unsigned int *matched_lid;
153+
154+ CudaDeviceFunction void Execute() const {
155+ using LA = ArbLatticeAccess;
156+ const int i = threadID(CudaThread, CudaBlock, CudaNumberOfThreads);
157+ if (inRange(i)) {
158+ LA acc(i, container);
159+ real_t X = acc.getX();
160+ real_t Y = acc.getY();
161+ real_t Z = acc.getZ();
162+ real_t distance = (X - point.x)*(X - point.x) + (Y - point.y)*(Y - point.y) + (Z - point.z)*(Z - point.z);
163+ if (distance < epsilon2) {
164+ *matched_lid= i;
165+ }
166+ }
167+ }
168+ };
169+
170+
171+ unsigned int ArbLatticeLauncher::getCartesianCoordinateLid(const vector_t point, const LatticeData& data) const {
172+ const auto gpu_lid = cudaMakeUnique<unsigned int>(1);
173+ const real_t tol2 = 1e-10;
174+ const CartesianCoordinateMapperArbExecutor executor{{container.num_border_nodes + container.num_interior_nodes}, container, data, point, tol2,
175+ gpu_lid.get()};
176+ LaunchExecutor(executor);
177+
178+ unsigned int matched_lid;
179+ CudaMemcpy(&matched_lid, gpu_lid.get(), sizeof(unsigned int), CudaMemcpyDeviceToHost);
180+ return matched_lid;
181+ }
182+
183+ void ArbLatticeLauncher::sampleQuantity(int quant, unsigned int lid, real_t* host_tab, real_t scale, const LatticeData &data) const {
184+ switch(quant) { <?R
185+ for (q in rows(Quantities)) { ifdef(q$adjoint);
186+ ?>
187+ case <?%s q$Index ?>: {
188+ const auto gpu_tab = cudaMakeUnique<<?%s q$type ?>>(1);
189+ getSample<?%s q$name ?>(gpu_tab.get(), scale, data, lid);
190+ CudaMemcpy(host_tab, gpu_tab.get(), sizeof(<?%s q$type ?>), CudaMemcpyDeviceToHost);
191+ break;
192+ } <?R
193+ }
194+ ifdef();
195+ ?>
196+ }
197+ }
198+
138199#endif // ARBLATTICELAUNCHER_HPP
0 commit comments