I am new to GPUDirect and I found an official example from this link. https://docs.nvidia.com/cuda/gpudirect-rdma/index.html. There is a section code as the following.
// for boundary alignment requirement
#define GPU_BOUND_SHIFT 16
#define GPU_BOUND_SIZE ((u64)1 << GPU_BOUND_SHIFT)
#define GPU_BOUND_OFFSET (GPU_BOUND_SIZE-1)
#define GPU_BOUND_MASK (~GPU_BOUND_OFFSET)
struct kmd_state {
nvidia_p2p_page_table_t *page_table;
// ...
};
void kmd_pin_memory(struct kmd_state *my_state, void *address, size_t size)
{
// do proper alignment, as required by NVIDIA kernel driver
u64 virt_start = address & GPU_BOUND_MASK;
size_t pin_size = address + size - virt_start;
if (!size)
return -EINVAL;
int ret = nvidia_p2p_get_pages(0, 0, virt_start, pin_size, &my_state->page_table, free_callback, &my_state);
if (ret == 0) {
// Succesfully pinned, page_table can be accessed
} else {
// Pinning failed
}
}
I am confused about the line 15 which is a bit operation. It seems that the GPU_BOUND_MASK is just 0…01111111111111111 where there are 16 ones and the rest are all zeros. I do not understand why this provides us a aligned pointer.