witwin-maxwell 0.3.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- witwin/maxwell/__init__.py +164 -0
- witwin/maxwell/adapters/__init__.py +1 -0
- witwin/maxwell/adapters/gds.py +203 -0
- witwin/maxwell/adapters/tidy3d.py +1669 -0
- witwin/maxwell/adjoint_inputs.py +70 -0
- witwin/maxwell/compiler/__init__.py +11 -0
- witwin/maxwell/compiler/materials.py +1355 -0
- witwin/maxwell/compiler/monitors.py +164 -0
- witwin/maxwell/compiler/sources.py +222 -0
- witwin/maxwell/fdfd/__init__.py +3 -0
- witwin/maxwell/fdfd/adjoint/__init__.py +3 -0
- witwin/maxwell/fdfd/adjoint/bridge.py +180 -0
- witwin/maxwell/fdfd/ams.py +300 -0
- witwin/maxwell/fdfd/krylov.py +280 -0
- witwin/maxwell/fdfd/plotting.py +110 -0
- witwin/maxwell/fdfd/postprocess.py +33 -0
- witwin/maxwell/fdfd/solver.py +1057 -0
- witwin/maxwell/fdtd/__init__.py +4 -0
- witwin/maxwell/fdtd/adjoint/__init__.py +21 -0
- witwin/maxwell/fdtd/adjoint/bridge.py +746 -0
- witwin/maxwell/fdtd/adjoint/capabilities.py +29 -0
- witwin/maxwell/fdtd/adjoint/core.py +3614 -0
- witwin/maxwell/fdtd/adjoint/dispatch.py +684 -0
- witwin/maxwell/fdtd/adjoint/native.py +2561 -0
- witwin/maxwell/fdtd/adjoint/profiler.py +195 -0
- witwin/maxwell/fdtd/adjoint/reverse_common.py +207 -0
- witwin/maxwell/fdtd/adjoint/seeds.py +524 -0
- witwin/maxwell/fdtd/boundary/__init__.py +37 -0
- witwin/maxwell/fdtd/boundary/bloch.py +90 -0
- witwin/maxwell/fdtd/boundary/common.py +41 -0
- witwin/maxwell/fdtd/boundary/cpml.py +527 -0
- witwin/maxwell/fdtd/boundary/runtime.py +209 -0
- witwin/maxwell/fdtd/checkpoint.py +227 -0
- witwin/maxwell/fdtd/coords.py +32 -0
- witwin/maxwell/fdtd/cuda/__init__.py +11 -0
- witwin/maxwell/fdtd/cuda/backend.py +3532 -0
- witwin/maxwell/fdtd/cuda/build.py +292 -0
- witwin/maxwell/fdtd/cuda/extension.cpp +2053 -0
- witwin/maxwell/fdtd/cuda/kernels/adjoint.cu +5290 -0
- witwin/maxwell/fdtd/cuda/kernels/aniso.cu +1704 -0
- witwin/maxwell/fdtd/cuda/kernels/boundary.cu +424 -0
- witwin/maxwell/fdtd/cuda/kernels/common.cu +74 -0
- witwin/maxwell/fdtd/cuda/kernels/common.cuh +82 -0
- witwin/maxwell/fdtd/cuda/kernels/dispersive.cu +782 -0
- witwin/maxwell/fdtd/cuda/kernels/electric.cu +3613 -0
- witwin/maxwell/fdtd/cuda/kernels/magnetic.cu +781 -0
- witwin/maxwell/fdtd/cuda/kernels/observers.cu +347 -0
- witwin/maxwell/fdtd/cuda/kernels/projection.cu +211 -0
- witwin/maxwell/fdtd/cuda/kernels/sources.cu +1482 -0
- witwin/maxwell/fdtd/cuda/kernels/spectral.cu +297 -0
- witwin/maxwell/fdtd/cuda/launch.h +23 -0
- witwin/maxwell/fdtd/cuda/prebuilt/witwin_maxwell_fdtd_cuda.pyd +0 -0
- witwin/maxwell/fdtd/cuda/runtime/__init__.py +6 -0
- witwin/maxwell/fdtd/cuda/runtime/dispatcher.py +6 -0
- witwin/maxwell/fdtd/cuda/runtime/graph.py +33 -0
- witwin/maxwell/fdtd/cuda/tensors.h +35 -0
- witwin/maxwell/fdtd/dispersion.py +48 -0
- witwin/maxwell/fdtd/evaluation.py +290 -0
- witwin/maxwell/fdtd/excitation/__init__.py +27 -0
- witwin/maxwell/fdtd/excitation/injection.py +1102 -0
- witwin/maxwell/fdtd/excitation/modes.py +1675 -0
- witwin/maxwell/fdtd/excitation/spatial.py +469 -0
- witwin/maxwell/fdtd/excitation/temporal.py +510 -0
- witwin/maxwell/fdtd/excitation/tfsf_apply.py +264 -0
- witwin/maxwell/fdtd/excitation/tfsf_common.py +421 -0
- witwin/maxwell/fdtd/excitation/tfsf_specs.py +490 -0
- witwin/maxwell/fdtd/excitation/tfsf_state.py +778 -0
- witwin/maxwell/fdtd/io.py +31 -0
- witwin/maxwell/fdtd/material_pullback.py +371 -0
- witwin/maxwell/fdtd/meshing/__init__.py +3 -0
- witwin/maxwell/fdtd/meshing/autogrid.py +335 -0
- witwin/maxwell/fdtd/observers.py +1453 -0
- witwin/maxwell/fdtd/plotting.py +121 -0
- witwin/maxwell/fdtd/postprocess.py +205 -0
- witwin/maxwell/fdtd/runtime/__init__.py +119 -0
- witwin/maxwell/fdtd/runtime/initialization.py +236 -0
- witwin/maxwell/fdtd/runtime/materials.py +1563 -0
- witwin/maxwell/fdtd/runtime/module_cache.py +31 -0
- witwin/maxwell/fdtd/runtime/spectral.py +581 -0
- witwin/maxwell/fdtd/runtime/stepping.py +1987 -0
- witwin/maxwell/fdtd/solver.py +502 -0
- witwin/maxwell/geometry/__init__.py +5 -0
- witwin/maxwell/geometry/polyslab.py +299 -0
- witwin/maxwell/materials.py +3 -0
- witwin/maxwell/media.py +1467 -0
- witwin/maxwell/monitors.py +743 -0
- witwin/maxwell/ports.py +113 -0
- witwin/maxwell/postprocess/RCS.py +139 -0
- witwin/maxwell/postprocess/__init__.py +42 -0
- witwin/maxwell/postprocess/diffraction.py +219 -0
- witwin/maxwell/postprocess/directivity.py +152 -0
- witwin/maxwell/postprocess/emission.py +67 -0
- witwin/maxwell/postprocess/modal.py +324 -0
- witwin/maxwell/postprocess/nfft.py +266 -0
- witwin/maxwell/postprocess/scattering_parameters.py +358 -0
- witwin/maxwell/postprocess/stratton_chu.py +1193 -0
- witwin/maxwell/result.py +967 -0
- witwin/maxwell/scene.py +1338 -0
- witwin/maxwell/simulation.py +659 -0
- witwin/maxwell/sources.py +917 -0
- witwin/maxwell/visualization/__init__.py +28 -0
- witwin/maxwell/visualization/interactive.py +484 -0
- witwin/maxwell/visualization/plots.py +568 -0
- witwin_maxwell-0.3.0.dist-info/METADATA +184 -0
- witwin_maxwell-0.3.0.dist-info/RECORD +107 -0
- witwin_maxwell-0.3.0.dist-info/WHEEL +4 -0
- witwin_maxwell-0.3.0.dist-info/licenses/LICENSE +13 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
#include <algorithm>
|
|
2
|
+
|
|
3
|
+
#include "../launch.h"
|
|
4
|
+
#include "../tensors.h"
|
|
5
|
+
#include "common.cuh"
|
|
6
|
+
|
|
7
|
+
namespace {
|
|
8
|
+
|
|
9
|
+
__global__ void accumulate_dft_batched_kernel(
|
|
10
|
+
int64_t ex_numel,
|
|
11
|
+
int64_t ey_numel,
|
|
12
|
+
int64_t ez_numel,
|
|
13
|
+
const float* __restrict__ ex,
|
|
14
|
+
const float* __restrict__ ey,
|
|
15
|
+
const float* __restrict__ ez,
|
|
16
|
+
const float* __restrict__ weighted_cos,
|
|
17
|
+
const float* __restrict__ weighted_sin,
|
|
18
|
+
float* __restrict__ ex_real,
|
|
19
|
+
float* __restrict__ ex_imag,
|
|
20
|
+
float* __restrict__ ey_real,
|
|
21
|
+
float* __restrict__ ey_imag,
|
|
22
|
+
float* __restrict__ ez_real,
|
|
23
|
+
float* __restrict__ ez_imag) {
|
|
24
|
+
const int64_t index = static_cast<int64_t>(blockIdx.x) * blockDim.x + threadIdx.x;
|
|
25
|
+
const int64_t freq = static_cast<int64_t>(blockIdx.y);
|
|
26
|
+
const float cos_value = weighted_cos[freq];
|
|
27
|
+
const float sin_value = weighted_sin[freq];
|
|
28
|
+
if (index < ex_numel) {
|
|
29
|
+
const int64_t linear = freq * ex_numel + index;
|
|
30
|
+
const float value = ex[index];
|
|
31
|
+
ex_real[linear] += value * cos_value;
|
|
32
|
+
ex_imag[linear] += value * sin_value;
|
|
33
|
+
}
|
|
34
|
+
if (index < ey_numel) {
|
|
35
|
+
const int64_t linear = freq * ey_numel + index;
|
|
36
|
+
const float value = ey[index];
|
|
37
|
+
ey_real[linear] += value * cos_value;
|
|
38
|
+
ey_imag[linear] += value * sin_value;
|
|
39
|
+
}
|
|
40
|
+
if (index < ez_numel) {
|
|
41
|
+
const int64_t linear = freq * ez_numel + index;
|
|
42
|
+
const float value = ez[index];
|
|
43
|
+
ez_real[linear] += value * cos_value;
|
|
44
|
+
ez_imag[linear] += value * sin_value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
__global__ void accumulate_dft_single_frequency_kernel(
|
|
49
|
+
int64_t ex_numel,
|
|
50
|
+
int64_t ey_numel,
|
|
51
|
+
int64_t ez_numel,
|
|
52
|
+
const float* __restrict__ ex,
|
|
53
|
+
const float* __restrict__ ey,
|
|
54
|
+
const float* __restrict__ ez,
|
|
55
|
+
const float* __restrict__ weighted_cos,
|
|
56
|
+
const float* __restrict__ weighted_sin,
|
|
57
|
+
float* __restrict__ ex_real,
|
|
58
|
+
float* __restrict__ ex_imag,
|
|
59
|
+
float* __restrict__ ey_real,
|
|
60
|
+
float* __restrict__ ey_imag,
|
|
61
|
+
float* __restrict__ ez_real,
|
|
62
|
+
float* __restrict__ ez_imag) {
|
|
63
|
+
const int64_t index = static_cast<int64_t>(blockIdx.x) * blockDim.x + threadIdx.x;
|
|
64
|
+
const float cos_value = weighted_cos[0];
|
|
65
|
+
const float sin_value = weighted_sin[0];
|
|
66
|
+
if (index < ex_numel) {
|
|
67
|
+
const float value = ex[index];
|
|
68
|
+
ex_real[index] += value * cos_value;
|
|
69
|
+
ex_imag[index] += value * sin_value;
|
|
70
|
+
}
|
|
71
|
+
if (index < ey_numel) {
|
|
72
|
+
const float value = ey[index];
|
|
73
|
+
ey_real[index] += value * cos_value;
|
|
74
|
+
ey_imag[index] += value * sin_value;
|
|
75
|
+
}
|
|
76
|
+
if (index < ez_numel) {
|
|
77
|
+
const float value = ez[index];
|
|
78
|
+
ez_real[index] += value * cos_value;
|
|
79
|
+
ez_imag[index] += value * sin_value;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
__global__ void accumulate_dft_frequency_coarsened_kernel(
|
|
84
|
+
int64_t max_field_numel,
|
|
85
|
+
int64_t frequency_count,
|
|
86
|
+
int64_t ex_numel,
|
|
87
|
+
int64_t ey_numel,
|
|
88
|
+
int64_t ez_numel,
|
|
89
|
+
const float* __restrict__ ex,
|
|
90
|
+
const float* __restrict__ ey,
|
|
91
|
+
const float* __restrict__ ez,
|
|
92
|
+
const float* __restrict__ weighted_cos,
|
|
93
|
+
const float* __restrict__ weighted_sin,
|
|
94
|
+
float* __restrict__ ex_real,
|
|
95
|
+
float* __restrict__ ex_imag,
|
|
96
|
+
float* __restrict__ ey_real,
|
|
97
|
+
float* __restrict__ ey_imag,
|
|
98
|
+
float* __restrict__ ez_real,
|
|
99
|
+
float* __restrict__ ez_imag) {
|
|
100
|
+
const int64_t index = static_cast<int64_t>(blockIdx.x) * blockDim.x + threadIdx.x;
|
|
101
|
+
if (index >= max_field_numel) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (index < ex_numel) {
|
|
105
|
+
const float value = ex[index];
|
|
106
|
+
for (int64_t freq = 0; freq < frequency_count; ++freq) {
|
|
107
|
+
const int64_t linear = freq * ex_numel + index;
|
|
108
|
+
ex_real[linear] += value * weighted_cos[freq];
|
|
109
|
+
ex_imag[linear] += value * weighted_sin[freq];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (index < ey_numel) {
|
|
113
|
+
const float value = ey[index];
|
|
114
|
+
for (int64_t freq = 0; freq < frequency_count; ++freq) {
|
|
115
|
+
const int64_t linear = freq * ey_numel + index;
|
|
116
|
+
ey_real[linear] += value * weighted_cos[freq];
|
|
117
|
+
ey_imag[linear] += value * weighted_sin[freq];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (index < ez_numel) {
|
|
121
|
+
const float value = ez[index];
|
|
122
|
+
for (int64_t freq = 0; freq < frequency_count; ++freq) {
|
|
123
|
+
const int64_t linear = freq * ez_numel + index;
|
|
124
|
+
ez_real[linear] += value * weighted_cos[freq];
|
|
125
|
+
ez_imag[linear] += value * weighted_sin[freq];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
__global__ void accumulate_dft_component_kernel(
|
|
131
|
+
int64_t field_numel,
|
|
132
|
+
const float* __restrict__ field,
|
|
133
|
+
const float* __restrict__ weighted_cos,
|
|
134
|
+
const float* __restrict__ weighted_sin,
|
|
135
|
+
float* __restrict__ real_accum,
|
|
136
|
+
float* __restrict__ imag_accum) {
|
|
137
|
+
const int64_t index = static_cast<int64_t>(blockIdx.x) * blockDim.x + threadIdx.x;
|
|
138
|
+
if (index >= field_numel) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const int64_t freq = static_cast<int64_t>(blockIdx.y);
|
|
142
|
+
const int64_t linear = freq * field_numel + index;
|
|
143
|
+
const float value = field[index];
|
|
144
|
+
real_accum[linear] += value * weighted_cos[freq];
|
|
145
|
+
imag_accum[linear] += value * weighted_sin[freq];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
void check_dft_component(
|
|
149
|
+
const torch::stable::Tensor& field,
|
|
150
|
+
const torch::stable::Tensor& real_accum,
|
|
151
|
+
const torch::stable::Tensor& imag_accum,
|
|
152
|
+
int64_t frequency_count,
|
|
153
|
+
const char* name) {
|
|
154
|
+
check_float32_tensor(field, name);
|
|
155
|
+
check_float32_tensor(real_accum, "real_accum");
|
|
156
|
+
check_float32_tensor(imag_accum, "imag_accum");
|
|
157
|
+
check_contiguous_tensor(field, name);
|
|
158
|
+
check_contiguous_tensor(real_accum, "real_accum");
|
|
159
|
+
check_contiguous_tensor(imag_accum, "imag_accum");
|
|
160
|
+
check_same_cuda_device(field, real_accum, "real_accum");
|
|
161
|
+
check_same_cuda_device(field, imag_accum, "imag_accum");
|
|
162
|
+
STD_TORCH_CHECK(real_accum.dim() == field.dim() + 1, "real_accum rank must be field rank + 1");
|
|
163
|
+
STD_TORCH_CHECK(imag_accum.sizes().equals(real_accum.sizes()), "imag_accum must match real_accum shape");
|
|
164
|
+
STD_TORCH_CHECK(real_accum.size(0) == frequency_count, "accum frequency dimension mismatch");
|
|
165
|
+
for (int64_t dim = 0; dim < field.dim(); ++dim) {
|
|
166
|
+
STD_TORCH_CHECK(real_accum.size(dim + 1) == field.size(dim), "accum spatial shape must match field");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
} // namespace
|
|
171
|
+
|
|
172
|
+
void accumulate_dft_batched_cuda(
|
|
173
|
+
const torch::stable::Tensor& ex,
|
|
174
|
+
const torch::stable::Tensor& ey,
|
|
175
|
+
const torch::stable::Tensor& ez,
|
|
176
|
+
torch::stable::Tensor ex_real,
|
|
177
|
+
torch::stable::Tensor ex_imag,
|
|
178
|
+
torch::stable::Tensor ey_real,
|
|
179
|
+
torch::stable::Tensor ey_imag,
|
|
180
|
+
torch::stable::Tensor ez_real,
|
|
181
|
+
torch::stable::Tensor ez_imag,
|
|
182
|
+
const torch::stable::Tensor& weighted_cos,
|
|
183
|
+
const torch::stable::Tensor& weighted_sin) {
|
|
184
|
+
check_float32_tensor(weighted_cos, "weighted_cos");
|
|
185
|
+
check_float32_tensor(weighted_sin, "weighted_sin");
|
|
186
|
+
check_contiguous_tensor(weighted_cos, "weighted_cos");
|
|
187
|
+
check_contiguous_tensor(weighted_sin, "weighted_sin");
|
|
188
|
+
STD_TORCH_CHECK(weighted_cos.dim() == 1, "weighted_cos must be rank 1");
|
|
189
|
+
STD_TORCH_CHECK(weighted_sin.sizes().equals(weighted_cos.sizes()), "weighted_sin must match weighted_cos");
|
|
190
|
+
const int64_t frequency_count = weighted_cos.size(0);
|
|
191
|
+
check_dft_component(ex, ex_real, ex_imag, frequency_count, "ex");
|
|
192
|
+
check_dft_component(ey, ey_real, ey_imag, frequency_count, "ey");
|
|
193
|
+
check_dft_component(ez, ez_real, ez_imag, frequency_count, "ez");
|
|
194
|
+
check_same_cuda_device(ex, ey, "ey");
|
|
195
|
+
check_same_cuda_device(ex, ez, "ez");
|
|
196
|
+
check_same_cuda_device(ex, weighted_cos, "weighted_cos");
|
|
197
|
+
check_same_cuda_device(ex, weighted_sin, "weighted_sin");
|
|
198
|
+
check_same_cuda_device(ex, ey_real, "ey_real");
|
|
199
|
+
check_same_cuda_device(ex, ey_imag, "ey_imag");
|
|
200
|
+
check_same_cuda_device(ex, ez_real, "ez_real");
|
|
201
|
+
check_same_cuda_device(ex, ez_imag, "ez_imag");
|
|
202
|
+
torch::stable::accelerator::DeviceGuard guard(ex.get_device_index());
|
|
203
|
+
const int64_t max_field_numel = std::max(ex.numel(), std::max(ey.numel(), ez.numel()));
|
|
204
|
+
constexpr int block_size = 256;
|
|
205
|
+
if (frequency_count == 1) {
|
|
206
|
+
accumulate_dft_single_frequency_kernel<<<linear_grid(max_field_numel, block_size), block_size, 0, current_cuda_stream()>>>(
|
|
207
|
+
ex.numel(),
|
|
208
|
+
ey.numel(),
|
|
209
|
+
ez.numel(),
|
|
210
|
+
ex.mutable_data_ptr<float>(),
|
|
211
|
+
ey.mutable_data_ptr<float>(),
|
|
212
|
+
ez.mutable_data_ptr<float>(),
|
|
213
|
+
weighted_cos.mutable_data_ptr<float>(),
|
|
214
|
+
weighted_sin.mutable_data_ptr<float>(),
|
|
215
|
+
ex_real.mutable_data_ptr<float>(),
|
|
216
|
+
ex_imag.mutable_data_ptr<float>(),
|
|
217
|
+
ey_real.mutable_data_ptr<float>(),
|
|
218
|
+
ey_imag.mutable_data_ptr<float>(),
|
|
219
|
+
ez_real.mutable_data_ptr<float>(),
|
|
220
|
+
ez_imag.mutable_data_ptr<float>());
|
|
221
|
+
} else if (
|
|
222
|
+
(frequency_count == 4 && max_field_numel < 1000000) ||
|
|
223
|
+
(frequency_count == 3 && max_field_numel >= 400000 && max_field_numel < 1000000)) {
|
|
224
|
+
accumulate_dft_frequency_coarsened_kernel<<<linear_grid(max_field_numel, block_size), block_size, 0, current_cuda_stream()>>>(
|
|
225
|
+
max_field_numel,
|
|
226
|
+
frequency_count,
|
|
227
|
+
ex.numel(),
|
|
228
|
+
ey.numel(),
|
|
229
|
+
ez.numel(),
|
|
230
|
+
ex.mutable_data_ptr<float>(),
|
|
231
|
+
ey.mutable_data_ptr<float>(),
|
|
232
|
+
ez.mutable_data_ptr<float>(),
|
|
233
|
+
weighted_cos.mutable_data_ptr<float>(),
|
|
234
|
+
weighted_sin.mutable_data_ptr<float>(),
|
|
235
|
+
ex_real.mutable_data_ptr<float>(),
|
|
236
|
+
ex_imag.mutable_data_ptr<float>(),
|
|
237
|
+
ey_real.mutable_data_ptr<float>(),
|
|
238
|
+
ey_imag.mutable_data_ptr<float>(),
|
|
239
|
+
ez_real.mutable_data_ptr<float>(),
|
|
240
|
+
ez_imag.mutable_data_ptr<float>());
|
|
241
|
+
} else if (frequency_count >= 4 && max_field_numel >= 1000000) {
|
|
242
|
+
const dim3 ex_grid(
|
|
243
|
+
static_cast<unsigned int>((ex.numel() + block_size - 1) / block_size),
|
|
244
|
+
static_cast<unsigned int>(frequency_count),
|
|
245
|
+
1);
|
|
246
|
+
const dim3 ey_grid(
|
|
247
|
+
static_cast<unsigned int>((ey.numel() + block_size - 1) / block_size),
|
|
248
|
+
static_cast<unsigned int>(frequency_count),
|
|
249
|
+
1);
|
|
250
|
+
const dim3 ez_grid(
|
|
251
|
+
static_cast<unsigned int>((ez.numel() + block_size - 1) / block_size),
|
|
252
|
+
static_cast<unsigned int>(frequency_count),
|
|
253
|
+
1);
|
|
254
|
+
accumulate_dft_component_kernel<<<ex_grid, block_size, 0, current_cuda_stream()>>>(
|
|
255
|
+
ex.numel(),
|
|
256
|
+
ex.mutable_data_ptr<float>(),
|
|
257
|
+
weighted_cos.mutable_data_ptr<float>(),
|
|
258
|
+
weighted_sin.mutable_data_ptr<float>(),
|
|
259
|
+
ex_real.mutable_data_ptr<float>(),
|
|
260
|
+
ex_imag.mutable_data_ptr<float>());
|
|
261
|
+
accumulate_dft_component_kernel<<<ey_grid, block_size, 0, current_cuda_stream()>>>(
|
|
262
|
+
ey.numel(),
|
|
263
|
+
ey.mutable_data_ptr<float>(),
|
|
264
|
+
weighted_cos.mutable_data_ptr<float>(),
|
|
265
|
+
weighted_sin.mutable_data_ptr<float>(),
|
|
266
|
+
ey_real.mutable_data_ptr<float>(),
|
|
267
|
+
ey_imag.mutable_data_ptr<float>());
|
|
268
|
+
accumulate_dft_component_kernel<<<ez_grid, block_size, 0, current_cuda_stream()>>>(
|
|
269
|
+
ez.numel(),
|
|
270
|
+
ez.mutable_data_ptr<float>(),
|
|
271
|
+
weighted_cos.mutable_data_ptr<float>(),
|
|
272
|
+
weighted_sin.mutable_data_ptr<float>(),
|
|
273
|
+
ez_real.mutable_data_ptr<float>(),
|
|
274
|
+
ez_imag.mutable_data_ptr<float>());
|
|
275
|
+
} else {
|
|
276
|
+
const dim3 grid(
|
|
277
|
+
static_cast<unsigned int>((max_field_numel + block_size - 1) / block_size),
|
|
278
|
+
static_cast<unsigned int>(frequency_count),
|
|
279
|
+
1);
|
|
280
|
+
accumulate_dft_batched_kernel<<<grid, block_size, 0, current_cuda_stream()>>>(
|
|
281
|
+
ex.numel(),
|
|
282
|
+
ey.numel(),
|
|
283
|
+
ez.numel(),
|
|
284
|
+
ex.mutable_data_ptr<float>(),
|
|
285
|
+
ey.mutable_data_ptr<float>(),
|
|
286
|
+
ez.mutable_data_ptr<float>(),
|
|
287
|
+
weighted_cos.mutable_data_ptr<float>(),
|
|
288
|
+
weighted_sin.mutable_data_ptr<float>(),
|
|
289
|
+
ex_real.mutable_data_ptr<float>(),
|
|
290
|
+
ex_imag.mutable_data_ptr<float>(),
|
|
291
|
+
ey_real.mutable_data_ptr<float>(),
|
|
292
|
+
ey_imag.mutable_data_ptr<float>(),
|
|
293
|
+
ez_real.mutable_data_ptr<float>(),
|
|
294
|
+
ez_imag.mutable_data_ptr<float>());
|
|
295
|
+
}
|
|
296
|
+
WITWIN_CUDA_CHECK();
|
|
297
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <torch/csrc/stable/accelerator.h>
|
|
4
|
+
#include <torch/csrc/stable/c/shim.h>
|
|
5
|
+
#include <torch/csrc/stable/macros.h>
|
|
6
|
+
|
|
7
|
+
#include <cuda_runtime.h>
|
|
8
|
+
|
|
9
|
+
inline dim3 linear_grid(long long elements, int block_size = 256) {
|
|
10
|
+
const auto blocks = (elements + block_size - 1) / block_size;
|
|
11
|
+
return dim3(static_cast<unsigned int>(blocks), 1, 1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
inline cudaStream_t current_cuda_stream() {
|
|
15
|
+
void* stream_ptr = nullptr;
|
|
16
|
+
TORCH_ERROR_CODE_CHECK(aoti_torch_get_current_cuda_stream(
|
|
17
|
+
torch::stable::accelerator::getCurrentDeviceIndex(),
|
|
18
|
+
&stream_ptr));
|
|
19
|
+
return static_cast<cudaStream_t>(stream_ptr);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
#define WITWIN_CUDA_CHECK() STD_CUDA_KERNEL_LAUNCH_CHECK()
|
|
23
|
+
|
|
Binary file
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
|
|
5
|
+
import torch
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CudaGraphRunner:
|
|
9
|
+
def __init__(self, *, enabled: bool = True, warmup_steps: int = 1):
|
|
10
|
+
self.enabled = bool(enabled)
|
|
11
|
+
self.warmup_steps = max(0, int(warmup_steps))
|
|
12
|
+
self.graph: torch.cuda.CUDAGraph | None = None
|
|
13
|
+
|
|
14
|
+
def capture(self, fn: Callable[[], None]) -> Callable[[], None]:
|
|
15
|
+
if not self.enabled:
|
|
16
|
+
return fn
|
|
17
|
+
if not torch.cuda.is_available():
|
|
18
|
+
raise RuntimeError("CUDA Graph capture requires CUDA.")
|
|
19
|
+
|
|
20
|
+
for _ in range(self.warmup_steps):
|
|
21
|
+
fn()
|
|
22
|
+
torch.cuda.synchronize()
|
|
23
|
+
|
|
24
|
+
graph = torch.cuda.CUDAGraph()
|
|
25
|
+
with torch.cuda.graph(graph):
|
|
26
|
+
fn()
|
|
27
|
+
torch.cuda.synchronize()
|
|
28
|
+
self.graph = graph
|
|
29
|
+
|
|
30
|
+
def replay() -> None:
|
|
31
|
+
graph.replay()
|
|
32
|
+
|
|
33
|
+
return replay
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <torch/csrc/stable/accelerator.h>
|
|
4
|
+
#include <torch/csrc/stable/tensor.h>
|
|
5
|
+
#include <torch/headeronly/core/ScalarType.h>
|
|
6
|
+
#include <torch/headeronly/macros/Macros.h>
|
|
7
|
+
|
|
8
|
+
#include <optional>
|
|
9
|
+
|
|
10
|
+
inline void check_cuda_tensor(const torch::stable::Tensor& tensor, const char* name) {
|
|
11
|
+
STD_TORCH_CHECK(tensor.is_cuda(), name, " must be a CUDA tensor");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
inline void check_same_cuda_device(
|
|
15
|
+
const torch::stable::Tensor& reference,
|
|
16
|
+
const torch::stable::Tensor& tensor,
|
|
17
|
+
const char* name) {
|
|
18
|
+
STD_TORCH_CHECK(
|
|
19
|
+
tensor.device() == reference.device(),
|
|
20
|
+
name,
|
|
21
|
+
" must be on the same CUDA device as the reference tensor");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
inline void check_float32_tensor(const torch::stable::Tensor& tensor, const char* name) {
|
|
25
|
+
check_cuda_tensor(tensor, name);
|
|
26
|
+
STD_TORCH_CHECK(
|
|
27
|
+
tensor.scalar_type() == torch::headeronly::ScalarType::Float,
|
|
28
|
+
name,
|
|
29
|
+
" must be float32");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
inline void check_contiguous_tensor(const torch::stable::Tensor& tensor, const char* name) {
|
|
33
|
+
STD_TORCH_CHECK(tensor.is_contiguous(), name, " must be contiguous");
|
|
34
|
+
}
|
|
35
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def solve_numerical_wavenumber(solver, direction, deltas) -> float:
|
|
7
|
+
"""Solve the discrete dispersion relation for |k|.
|
|
8
|
+
|
|
9
|
+
``deltas`` maps axis name ("x"/"y"/"z") to the grid spacing (float) to use
|
|
10
|
+
along that axis — the locally uniform spacing of the injection region.
|
|
11
|
+
"""
|
|
12
|
+
omega = float(solver.source_omega)
|
|
13
|
+
if omega <= 0.0:
|
|
14
|
+
return 0.0
|
|
15
|
+
|
|
16
|
+
target = math.sin(0.5 * omega * float(solver.dt)) ** 2 / (float(solver.c) ** 2 * float(solver.dt) ** 2)
|
|
17
|
+
if target <= 0.0:
|
|
18
|
+
return omega / float(solver.c)
|
|
19
|
+
|
|
20
|
+
axis_limits = []
|
|
21
|
+
for axis, component in zip("xyz", direction):
|
|
22
|
+
abs_component = abs(float(component))
|
|
23
|
+
if abs_component <= 1e-12:
|
|
24
|
+
continue
|
|
25
|
+
delta = float(deltas[axis])
|
|
26
|
+
axis_limits.append(2.0 * math.pi / max(abs_component * delta, 1e-30))
|
|
27
|
+
if not axis_limits:
|
|
28
|
+
return omega / float(solver.c)
|
|
29
|
+
|
|
30
|
+
def dispersion_residual(k_mag):
|
|
31
|
+
total = 0.0
|
|
32
|
+
for axis, component in zip("xyz", direction):
|
|
33
|
+
abs_component = abs(float(component))
|
|
34
|
+
if abs_component <= 1e-12:
|
|
35
|
+
continue
|
|
36
|
+
delta = float(deltas[axis])
|
|
37
|
+
total += math.sin(0.5 * k_mag * abs_component * delta) ** 2 / (delta * delta)
|
|
38
|
+
return total - target
|
|
39
|
+
|
|
40
|
+
low = 0.0
|
|
41
|
+
high = min(axis_limits)
|
|
42
|
+
for _ in range(80):
|
|
43
|
+
mid = 0.5 * (low + high)
|
|
44
|
+
if dispersion_residual(mid) >= 0.0:
|
|
45
|
+
high = mid
|
|
46
|
+
else:
|
|
47
|
+
low = mid
|
|
48
|
+
return 0.5 * (low + high)
|