//===-- Generic device loader interface -----------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #ifndef LLVM_LIBC_UTILS_GPU_LOADER_LOADER_H #define LLVM_LIBC_UTILS_GPU_LOADER_LOADER_H #include #include #include /// Generic interface to load the \p image and launch execution of the _start /// kernel on the target device. Copies \p argc and \p argv to the device. /// Returns the final value of the `main` function on the device. int load(int argc, char **argv, char **evnp, void *image, size_t size); /// Copy the system's argument vector to GPU memory allocated using \p alloc. template void *copy_argument_vector(int argc, char **argv, Allocator alloc) { size_t argv_size = sizeof(char *) * (argc + 1); size_t str_size = 0; for (int i = 0; i < argc; ++i) str_size += strlen(argv[i]) + 1; // We allocate enough space for a null terminated array and all the strings. void *dev_argv = alloc(argv_size + str_size); if (!dev_argv) return nullptr; // Store the strings linerally in the same memory buffer. void *dev_str = reinterpret_cast(dev_argv) + argv_size; for (int i = 0; i < argc; ++i) { size_t size = strlen(argv[i]) + 1; std::memcpy(dev_str, argv[i], size); static_cast(dev_argv)[i] = dev_str; dev_str = reinterpret_cast(dev_str) + size; } // Ensure the vector is null terminated. reinterpret_cast(dev_argv)[argv_size] = nullptr; return dev_argv; }; /// Copy the system's environment to GPU memory allocated using \p alloc. template void *copy_environment(char **envp, Allocator alloc) { int envc = 0; for (char **env = envp; *env != 0; ++env) ++envc; return copy_argument_vector(envc, envp, alloc); }; #endif