15#ifndef OPENJIJ_SYSTEM_CHIMERA_GPU_TRANSVERSE_HPP__
16#define OPENJIJ_SYSTEM_CHIMERA_GPU_TRANSVERSE_HPP__
37template <
typename FloatType>
struct ChimeraInteractions {
39 utility::cuda::unique_dev_ptr<FloatType[]> J_out_p;
40 utility::cuda::unique_dev_ptr<FloatType[]> J_out_n;
41 utility::cuda::unique_dev_ptr<FloatType[]> J_in_04;
42 utility::cuda::unique_dev_ptr<FloatType[]> J_in_15;
43 utility::cuda::unique_dev_ptr<FloatType[]> J_in_26;
44 utility::cuda::unique_dev_ptr<FloatType[]> J_in_37;
45 utility::cuda::unique_dev_ptr<FloatType[]> h;
47 ChimeraInteractions(std::size_t n)
48 : J_out_p(utility::cuda::make_dev_unique<
FloatType[]>(n)),
49 J_out_n(utility::cuda::make_dev_unique<
FloatType[]>(n)),
50 J_in_04(utility::cuda::make_dev_unique<
FloatType[]>(n)),
51 J_in_15(utility::cuda::make_dev_unique<
FloatType[]>(n)),
52 J_in_26(utility::cuda::make_dev_unique<
FloatType[]>(n)),
53 J_in_37(utility::cuda::make_dev_unique<
FloatType[]>(n)),
54 h(utility::cuda::make_dev_unique<
FloatType[]>(n)) {}
65template <
typename FloatType, std::size_t rows_per_block = 2,
66 std::size_t cols_per_block = 2, std::size_t trotters_per_block = 2>
67struct ChimeraTransverseGPU {
68 using system_type = transverse_field_system;
78 ChimeraTransverseGPU(
const TrotterSpins &init_trotter_spins,
79 const graph::Chimera<FloatType> &init_interaction,
80 FloatType gamma,
int device_num = 0)
82 info({init_interaction.get_num_row(), init_interaction.get_num_column(),
83 init_trotter_spins.size()}),
84 interaction(init_interaction.get_num_row() *
85 init_interaction.get_num_column() * info.chimera_unitsize),
86 spin(utility::cuda::make_dev_unique<std::int32_t[]>(
87 init_interaction.get_num_row() * init_interaction.get_num_column() *
88 info.chimera_unitsize * init_trotter_spins.size())),
89 grid(dim3(init_interaction.get_num_column() / cols_per_block,
90 init_interaction.get_num_row() / rows_per_block,
91 init_trotter_spins.size() / trotters_per_block)),
92 block(dim3(info.chimera_unitsize * cols_per_block, rows_per_block,
94 dev_random(utility::cuda::make_dev_unique<FloatType[]>(
95 init_interaction.get_num_row() * init_interaction.get_num_column() *
96 info.chimera_unitsize * init_trotter_spins.size())) {
98 if (!(info.rows % rows_per_block == 0 && info.cols % cols_per_block == 0 &&
99 info.trotters % trotters_per_block == 0)) {
100 throw std::invalid_argument(
"invalid number of rows, cols, or trotters");
104 initialize_gpu(init_interaction, init_trotter_spins, device_num);
116 ChimeraTransverseGPU(
const graph::Spins &classical_spins,
117 const graph::Chimera<FloatType> &init_interaction,
118 FloatType gamma,
size_t num_trotter_slices,
121 info({init_interaction.get_num_row(), init_interaction.get_num_column(),
122 num_trotter_slices}),
123 interaction(init_interaction.get_num_row() *
124 init_interaction.get_num_column() * info.chimera_unitsize),
125 spin(utility::cuda::make_dev_unique<std::int32_t[]>(
126 init_interaction.get_num_row() * init_interaction.get_num_column() *
127 info.chimera_unitsize * num_trotter_slices)),
128 grid(dim3(init_interaction.get_num_column() / cols_per_block,
129 init_interaction.get_num_row() / rows_per_block,
130 num_trotter_slices / trotters_per_block)),
131 block(dim3(info.chimera_unitsize * cols_per_block, rows_per_block,
132 trotters_per_block)),
133 dev_random(utility::cuda::make_dev_unique<FloatType[]>(
134 init_interaction.get_num_row() * init_interaction.get_num_column() *
135 info.chimera_unitsize * num_trotter_slices)) {
137 if (!(info.rows % rows_per_block == 0 && info.cols % cols_per_block == 0 &&
138 info.trotters % trotters_per_block == 0)) {
139 throw std::invalid_argument(
"invalid number of rows, cols, or trotters");
143 for (
auto &spins : trotter_spins) {
144 spins = classical_spins;
148 initialize_gpu(init_interaction, trotter_spins, device_num);
156 void reset_spins(
const TrotterSpins &init_trotter_spins) {
158 const std::size_t localsize = info.rows * info.cols * info.chimera_unitsize;
160 utility::cuda::make_host_unique<int32_t[]>(localsize * info.trotters);
162 using namespace chimera_cuda;
164 for (
size_t t = 0; t < info.trotters; t++) {
165 for (
size_t r = 0; r < info.rows; r++) {
166 for (
size_t c = 0; c < info.cols; c++) {
167 for (
size_t i = 0; i < info.chimera_unitsize; i++) {
168 temp_spin[glIdx(info, r, c, i, t)] =
169 init_trotter_spins[t][glIdx(info, r, c, i)];
175 HANDLE_ERROR_CUDA(cudaMemcpy(spin.get(), temp_spin.get(),
176 localsize * info.trotters *
sizeof(int32_t),
177 cudaMemcpyHostToDevice));
185 void reset_spins(
const graph::Spins &classical_spins) {
189 for (
auto &spins : init_trotter_spins) {
190 spins = classical_spins;
194 const std::size_t localsize = info.rows * info.cols * info.chimera_unitsize;
196 utility::cuda::make_host_unique<int32_t[]>(localsize * info.trotters);
198 using namespace chimera_cuda;
200 for (
size_t t = 0; t < info.trotters; t++) {
201 for (
size_t r = 0; r < info.rows; r++) {
202 for (
size_t c = 0; c < info.cols; c++) {
203 for (
size_t i = 0; i < info.chimera_unitsize; i++) {
204 temp_spin[glIdx(info, r, c, i, t)] =
205 init_trotter_spins[t][glIdx(info, r, c, i)];
211 HANDLE_ERROR_CUDA(cudaMemcpy(spin.get(), temp_spin.get(),
212 localsize * info.trotters *
sizeof(int32_t),
213 cudaMemcpyHostToDevice));
224 const ChimeraInfo info;
229 ChimeraInteractions<FloatType> interaction;
234 utility::cuda::unique_dev_ptr<std::int32_t[]> spin;
249 utility::cuda::unique_dev_ptr<FloatType[]> dev_random;
259 inline void initialize_gpu(
const graph::Chimera<FloatType> &init_interaction,
260 const TrotterSpins &trotter_spins,
int gpu_num) {
263 HANDLE_ERROR_CUDA(cudaSetDevice(gpu_num));
266 const std::size_t localsize = info.rows * info.cols * info.chimera_unitsize;
268 auto J_out_p = utility::cuda::make_host_unique<FloatType[]>(localsize);
269 auto J_out_n = utility::cuda::make_host_unique<FloatType[]>(localsize);
270 auto J_in_04 = utility::cuda::make_host_unique<FloatType[]>(localsize);
271 auto J_in_15 = utility::cuda::make_host_unique<FloatType[]>(localsize);
272 auto J_in_26 = utility::cuda::make_host_unique<FloatType[]>(localsize);
273 auto J_in_37 = utility::cuda::make_host_unique<FloatType[]>(localsize);
274 auto h = utility::cuda::make_host_unique<FloatType[]>(localsize);
276 utility::cuda::make_host_unique<int32_t[]>(localsize * info.trotters);
278 using namespace chimera_cuda;
281 for (
size_t r = 0; r < info.rows; r++) {
282 for (
size_t c = 0; c < info.cols; c++) {
283 for (
size_t i = 0; i < info.chimera_unitsize; i++) {
285 J_out_p[glIdx(info, r, c, i)] = 0;
286 J_out_n[glIdx(info, r, c, i)] = 0;
287 J_in_04[glIdx(info, r, c, i)] = 0;
288 J_in_15[glIdx(info, r, c, i)] = 0;
289 J_in_26[glIdx(info, r, c, i)] = 0;
290 J_in_37[glIdx(info, r, c, i)] = 0;
291 h[glIdx(info, r, c, i)] = 0;
293 if (r > 0 && i < 4) {
295 J_out_p[glIdx(info, r, c, i)] =
296 init_interaction.J(r, c, i, graph::ChimeraDir::MINUS_R);
298 if (c > 0 && 4 <= i) {
300 J_out_p[glIdx(info, r, c, i)] =
301 init_interaction.J(r, c, i, graph::ChimeraDir::MINUS_C);
303 if (r < info.rows - 1 && i < 4) {
305 J_out_n[glIdx(info, r, c, i)] =
306 init_interaction.J(r, c, i, graph::ChimeraDir::PLUS_R);
308 if (c < info.cols - 1 && 4 <= i) {
310 J_out_n[glIdx(info, r, c, i)] =
311 init_interaction.J(r, c, i, graph::ChimeraDir::PLUS_C);
315 J_in_04[glIdx(info, r, c, i)] =
316 init_interaction.J(r, c, i, graph::ChimeraDir::IN_0or4);
317 J_in_15[glIdx(info, r, c, i)] =
318 init_interaction.J(r, c, i, graph::ChimeraDir::IN_1or5);
319 J_in_26[glIdx(info, r, c, i)] =
320 init_interaction.J(r, c, i, graph::ChimeraDir::IN_2or6);
321 J_in_37[glIdx(info, r, c, i)] =
322 init_interaction.J(r, c, i, graph::ChimeraDir::IN_3or7);
325 h[glIdx(info, r, c, i)] = init_interaction.h(r, c, i);
331 for (
size_t t = 0; t < info.trotters; t++) {
332 for (
size_t r = 0; r < info.rows; r++) {
333 for (
size_t c = 0; c < info.cols; c++) {
334 for (
size_t i = 0; i < info.chimera_unitsize; i++) {
335 temp_spin[glIdx(info, r, c, i, t)] =
336 trotter_spins[t][init_interaction.to_ind(r, c, i)];
343 HANDLE_ERROR_CUDA(cudaMemcpy(interaction.J_out_p.get(), J_out_p.get(),
344 localsize *
sizeof(FloatType),
345 cudaMemcpyHostToDevice));
346 HANDLE_ERROR_CUDA(cudaMemcpy(interaction.J_out_n.get(), J_out_n.get(),
347 localsize *
sizeof(FloatType),
348 cudaMemcpyHostToDevice));
349 HANDLE_ERROR_CUDA(cudaMemcpy(interaction.J_in_04.get(), J_in_04.get(),
350 localsize *
sizeof(FloatType),
351 cudaMemcpyHostToDevice));
352 HANDLE_ERROR_CUDA(cudaMemcpy(interaction.J_in_15.get(), J_in_15.get(),
353 localsize *
sizeof(FloatType),
354 cudaMemcpyHostToDevice));
355 HANDLE_ERROR_CUDA(cudaMemcpy(interaction.J_in_26.get(), J_in_26.get(),
356 localsize *
sizeof(FloatType),
357 cudaMemcpyHostToDevice));
358 HANDLE_ERROR_CUDA(cudaMemcpy(interaction.J_in_37.get(), J_in_37.get(),
359 localsize *
sizeof(FloatType),
360 cudaMemcpyHostToDevice));
361 HANDLE_ERROR_CUDA(cudaMemcpy(interaction.h.get(), h.get(),
362 localsize *
sizeof(FloatType),
363 cudaMemcpyHostToDevice));
365 HANDLE_ERROR_CUDA(cudaMemcpy(spin.get(), temp_spin.get(),
366 localsize * info.trotters *
sizeof(int32_t),
367 cudaMemcpyHostToDevice));
385template <std::size_t rows_per_block = 2, std::size_t cols_per_block = 2,
386 std::size_t trotters_per_block = 2,
typename FloatType>
387ChimeraTransverseGPU<
FloatType, rows_per_block, cols_per_block,
389make_chimera_transverse_gpu(
const TrotterSpins &init_trotter_spins,
391 double gamma,
int device_num = 0) {
392 return ChimeraTransverseGPU<
FloatType, rows_per_block, cols_per_block,
394 init_trotter_spins, init_interaction, gamma, device_num);
411template <std::size_t rows_per_block = 2, std::size_t cols_per_block = 2,
412 std::size_t trotters_per_block = 2,
typename FloatType>
413ChimeraTransverseGPU<
FloatType, rows_per_block, cols_per_block,
415make_chimera_transverse_gpu(
const graph::Spins &classical_spins,
417 double gamma,
size_t num_trotter_slices,
418 int device_num = 0) {
419 return ChimeraTransverseGPU<
FloatType, rows_per_block, cols_per_block,
421 classical_spins, init_interaction, gamma, num_trotter_slices, device_num);
auto json_parse(const json &obj, bool relabel=true)
parse json object from bqm.to_serializable
Definition parse.hpp:50
std::vector< Spin > Spins
Definition graph.hpp:27
std::vector< graph::Spins > TrotterSpins
trotterized spin (std::vector<Spins>) trotter_spins[i][j] -> jth spin in ith trotter slice.
Definition transverse_ising.hpp:32
Definition algorithm.hpp:24
double FloatType
Note:
Definition compile_config.hpp:37