Files
clang-p2996/libc/startup/gpu/nvptx/start.cpp
Joseph Huber 50445dff43 [libc] Add more utility functions for the GPU
This patch adds extra intrinsics for the GPU. Some of these are unused
for now but will be used later. We use these currently to update the
`RPC` handling. Currently, every thread can update the RPC client, which
isn't correct. This patch adds code neccesary to allow a single thread
to perfrom the write while the others wait.

Feedback is welcome for the naming of these functions. I'm copying the
OpenMP nomenclature where we call an AMD `wavefront` or NVIDIA `warp` a
`lane`.

Reviewed By: tra

Differential Revision: https://reviews.llvm.org/D148810
2023-04-24 15:47:53 -05:00

44 lines
1.4 KiB
C++

//===-- Implementation of crt for nvptx -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/__support/GPU/utils.h"
#include "src/__support/RPC/rpc_client.h"
extern "C" int main(int argc, char **argv, char **envp);
namespace __llvm_libc {
static cpp::Atomic<uint32_t> lock = 0;
static cpp::Atomic<uint32_t> init = 0;
void init_rpc(void *in, void *out, void *buffer) {
// Only a single thread should update the RPC data.
if (gpu::get_thread_id() == 0 && gpu::get_block_id() == 0) {
rpc::client.reset(&lock, in, out, buffer);
init.store(1, cpp::MemoryOrder::RELAXED);
}
// Wait until the previous thread signals that the data has been written.
while (!init.load(cpp::MemoryOrder::RELAXED))
rpc::sleep_briefly();
// Wait for the threads in the block to converge and fence the write.
gpu::sync_threads();
}
} // namespace __llvm_libc
extern "C" [[gnu::visibility("protected"), clang::nvptx_kernel]] void
_start(int argc, char **argv, char **envp, int *ret, void *in, void *out,
void *buffer) {
__llvm_libc::init_rpc(in, out, buffer);
__atomic_fetch_or(ret, main(argc, argv, envp), __ATOMIC_RELAXED);
}