Repository navigation
Fuse the pusher preamble into one CUDA kernel #708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| /** | ||
| * Prepare the marker buffer for a push, as the three column-slice assignments at the start of Pusher._push: | ||
| * | ||
| * markers[:, first_init_idx:first_shift_idx] = markers[:, :n_init] | ||
| * markers[:, first_shift_idx:residual_idx] = 0.0 | ||
| * markers[:, residual_idx:-2] = 0.0 | ||
| * | ||
| * One thread per entry of the contiguous column range [first_init_idx, n_cols - 2) of every row, so that | ||
| * neighbouring threads write neighbouring addresses of the row-major buffer and the whole range is written | ||
| * in a single pass (instead of one strided pass over the buffer per slice). | ||
| * | ||
| * @param markers Marker buffer (n_rows x n_cols, row-major), every row including holes. | ||
| * @param n_rows Number of rows of the buffer. | ||
| * @param n_cols Number of columns of the buffer. | ||
| * @param first_init_idx First column of the saved initial phase space coordinates. | ||
| * @param n_init Number of saved coordinates, 3 + vdim (first_shift_idx = first_init_idx + n_init). | ||
| */ | ||
| extern "C" __global__ void prepare_push(double* markers, long long n_rows, int n_cols, int first_init_idx, | ||
| int n_init) { | ||
| long long width = n_cols - 2 - first_init_idx; | ||
| long long t = (long long)blockDim.x * blockIdx.x + threadIdx.x; | ||
| if (t >= n_rows * width) return; | ||
|
|
||
| long long ip = t / width; | ||
| int col = first_init_idx + (int)(t - ip * width); | ||
| double* row = markers + ip * n_cols; | ||
| row[col] = col < first_init_idx + n_init ? row[col - first_init_idx] : 0.0; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| "Accelerated particle pushing." | ||
|
|
||
| import logging | ||
| from functools import cache | ||
| from pathlib import Path | ||
|
|
||
| import cunumpy as xp | ||
| from cunumpy.kernels import Kernel, PyccelKernel | ||
| from cunumpy.kernels import CudaKernel, Kernel, PyccelKernel | ||
| from line_profiler import profile | ||
| from maybempi import MPI | ||
| from scope_profiler import ProfileManager | ||
|
|
@@ -16,6 +18,13 @@ | |
| logger = logging.getLogger("struphy") | ||
|
|
||
|
|
||
| @cache | ||
| def _prepare_push_cuda() -> CudaKernel: | ||
| """The CUDA kernel that fuses the column-slice assignments at the start of :meth:`Pusher._push` | ||
| (compiled on first call).""" | ||
| return CudaKernel.from_file(Path(__file__).with_name("prepare_push_cuda.cu"), "prepare_push") | ||
|
|
||
|
|
||
| class Pusher: | ||
| r""" | ||
| Class for solving particle ODEs | ||
|
|
@@ -208,17 +217,29 @@ def _push(self, dt: float): | |
| logger.debug(f"{residual_idx =}") | ||
| logger.debug(f"{self.particles.n_cols =}") | ||
|
|
||
| init_slice = slice(first_pusher_idx, first_shift_idx) | ||
| shift_slice = slice(first_shift_idx, residual_idx) | ||
| if self._cuda: | ||
| # the three assignments below in one pass over the buffer (each slice is a strided pass on its own) | ||
| n_rows, n_cols = markers.shape | ||
| _prepare_push_cuda()( | ||
| markers, | ||
| n_rows, | ||
| n_cols, | ||
| first_pusher_idx, | ||
| 3 + vdim, | ||
| n_threads=n_rows * (n_cols - 2 - first_pusher_idx), | ||
| ) | ||
| else: | ||
| init_slice = slice(first_pusher_idx, first_shift_idx) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this called |
||
| shift_slice = slice(first_shift_idx, residual_idx) | ||
|
|
||
| # save initial phase space coordinates | ||
| markers[:, init_slice] = markers[:, : 3 + vdim] | ||
| # save initial phase space coordinates | ||
| markers[:, init_slice] = markers[:, : 3 + vdim] | ||
|
|
||
| # set boundary shifts to zero | ||
| markers[:, shift_slice] = 0.0 | ||
| # set boundary shifts to zero | ||
| markers[:, shift_slice] = 0.0 | ||
|
|
||
| # clear buffer columns starting from residual index, dont clear ID (last column) and loc_box | ||
| markers[:, residual_idx:-2] = 0.0 | ||
| # clear buffer columns starting from residual index, dont clear ID (last column) and loc_box | ||
| markers[:, residual_idx:-2] = 0.0 | ||
|
|
||
| rank = self.particles.mpi_rank | ||
| logger.debug(f"rank {rank}: starting {self.kernel} ...") | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
explain this line for Python people