jhuber6 updated this revision to Diff 554434. jhuber6 added a comment. Address nits and add static check for size of `clock_t` type.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D159118/new/ https://reviews.llvm.org/D159118 Files: clang/lib/Headers/llvm_libc_wrappers/time.h libc/config/gpu/api.td libc/config/gpu/entrypoints.txt libc/config/gpu/headers.txt libc/docs/gpu/support.rst libc/include/llvm-libc-macros/gpu/CMakeLists.txt libc/include/llvm-libc-macros/gpu/time-macros.h libc/include/llvm-libc-macros/time-macros.h libc/src/time/gpu/CMakeLists.txt libc/src/time/gpu/clock.cpp
Index: libc/src/time/gpu/clock.cpp =================================================================== --- /dev/null +++ libc/src/time/gpu/clock.cpp @@ -0,0 +1,64 @@ +//===-- GPU implementation of the clock function --------------------------===// +// +// 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/time/clock.h" +#include "src/__support/GPU/utils.h" + +namespace __llvm_libc { + +#if defined(LIBC_TARGET_ARCH_IS_GPU) +// AMDGPU does not have a single set frequency. Different architectures and +// cards can have vary values. Here we default to a few known values, but for +// complete support the frequency needs to be read from the kernel driver. +#if defined(__gfx1010__) || defined(__gfx1011__) || defined(__gfx1012__) || \ + defined(__gfx1013__) || defined(__gfx1030__) || defined(__gfx1031__) || \ + defined(__gfx1032__) || defined(__gfx1033__) || defined(__gfx1034__) || \ + defined(__gfx1035__) || defined(__gfx1036__) || defined(__gfx1100__) || \ + defined(__gfx1101__) || defined(__gfx1102__) || defined(__gfx1103__) || \ + defined(__gfx1150__) || defined(__gfx1151__) +// These architectures use a 100 MHz fixed frequency clock. +constexpr uint64_t clock_freq = 100000000; +#elif defined(__gfx900__) || defined(__gfx902__) || defined(__gfx904__) || \ + defined(__gfx906__) || defined(__gfx908__) || defined(__gfx909__) || \ + defined(__gfx90a__) || defined(__gfx90c__) || defined(__gfx940__) +// These architectures use a 25 MHz fixed frequency clock expect for Vega 10 +// which is actually 27 Mhz. We default to 25 MHz in all cases anyway. +constexpr uint64_t clock_freq = 25000000; +#else +// The frequency for these architecture is unknown. We simply default to zero. +constexpr uint64_t clock_freq = 0; +#endif + +// We provide an externally visible symbol such that the runtime can set this to +// the correct value. If it is not set we try to default to the known values. +extern "C" [[gnu::visibility("protected")]] uint64_t + [[clang::address_space(4)]] __llvm_libc_clock_freq = clock_freq; +#define GPU_CLOCKS_PER_SEC static_cast<clock_t>(__llvm_libc_clock_freq) + +#elif defined(LIBC_TARGET_ARCH_IS_NVPTX) +// NPVTX uses a single 1 GHz fixed frequency clock for all target architectures. +#define GPU_CLOCKS_PER_SEC static_cast<clock_t>(1000000000UL) +#else +#error "Unsupported target" +#endif + +LLVM_LIBC_FUNCTION(clock_t, clock, ()) { + if (!GPU_CLOCKS_PER_SEC) + return clock_t(0); + + uint64_t ticks = gpu::fixed_frequency_clock(); + + // We need to convert between the GPU's fixed frequency and whatever `time.h` + // declares it to be. This is done so that dividing the result of this + // function by 'CLOCKS_PER_SEC' yields the elapsed time. + if (GPU_CLOCKS_PER_SEC > CLOCKS_PER_SEC) + return clock_t(ticks / (GPU_CLOCKS_PER_SEC / CLOCKS_PER_SEC)); + return clock_t(ticks * (CLOCKS_PER_SEC / GPU_CLOCKS_PER_SEC)); +} + +} // namespace __llvm_libc Index: libc/src/time/gpu/CMakeLists.txt =================================================================== --- /dev/null +++ libc/src/time/gpu/CMakeLists.txt @@ -0,0 +1,10 @@ +add_entrypoint_object( + clock + SRCS + clock.cpp + HDRS + ../clock.h + DEPENDS + libc.include.time + libc.src.__support.GPU.utils +) Index: libc/include/llvm-libc-macros/time-macros.h =================================================================== --- libc/include/llvm-libc-macros/time-macros.h +++ libc/include/llvm-libc-macros/time-macros.h @@ -3,6 +3,8 @@ #ifdef __linux__ #include "linux/time-macros.h" +#elif defined(__AMDGPU__) || defined(__NVPTX__) +#include "gpu/time-macros.h" #endif #endif // __LLVM_LIBC_MACROS_TIME_MACROS_H Index: libc/include/llvm-libc-macros/gpu/time-macros.h =================================================================== --- /dev/null +++ libc/include/llvm-libc-macros/gpu/time-macros.h @@ -0,0 +1,14 @@ +//===-- Definition of macros from time.h ---------------------------------===// +// +// 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_MACROS_GPU_TIME_MACROS_H +#define __LLVM_LIBC_MACROS_GPU_TIME_MACROS_H + +#define CLOCKS_PER_SEC 1000000 + +#endif // __LLVM_LIBC_MACROS_GPU_TIME_MACROS_H Index: libc/include/llvm-libc-macros/gpu/CMakeLists.txt =================================================================== --- /dev/null +++ libc/include/llvm-libc-macros/gpu/CMakeLists.txt @@ -0,0 +1,5 @@ +add_header( + time_macros + HDR + time-macros.h +) Index: libc/docs/gpu/support.rst =================================================================== --- libc/docs/gpu/support.rst +++ libc/docs/gpu/support.rst @@ -128,3 +128,12 @@ fopen |check| |check| fread |check| |check| ============= ========= ============ + +stdio.h +-------- + +============= ========= ============ +Function Name Available RPC Required +============= ========= ============ +clock |check| +============= ========= ============ Index: libc/config/gpu/headers.txt =================================================================== --- libc/config/gpu/headers.txt +++ libc/config/gpu/headers.txt @@ -4,6 +4,7 @@ libc.include.inttypes libc.include.math libc.include.fenv + libc.include.time libc.include.errno libc.include.stdlib libc.include.stdio Index: libc/config/gpu/entrypoints.txt =================================================================== --- libc/config/gpu/entrypoints.txt +++ libc/config/gpu/entrypoints.txt @@ -96,6 +96,9 @@ libc.src.inttypes.strtoimax libc.src.inttypes.strtoumax + # time.h entrypoints + libc.src.time.clock + # gpu/rpc.h entrypoints libc.src.gpu.rpc_reset libc.src.gpu.rpc_host_call Index: libc/config/gpu/api.td =================================================================== --- libc/config/gpu/api.td +++ libc/config/gpu/api.td @@ -34,3 +34,9 @@ def IntTypesAPI : PublicAPI<"inttypes.h"> { let Types = ["imaxdiv_t"]; } + +def TimeAPI : PublicAPI<"time.h"> { + let Types = [ + "clock_t", + ]; +} Index: clang/lib/Headers/llvm_libc_wrappers/time.h =================================================================== --- /dev/null +++ clang/lib/Headers/llvm_libc_wrappers/time.h @@ -0,0 +1,34 @@ +//===-- Wrapper for C standard time.h declarations on the GPU -------------===// +// +// 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 __CLANG_LLVM_LIBC_WRAPPERS_TIME_H__ +#define __CLANG_LLVM_LIBC_WRAPPERS_TIME_H__ + +#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__) +#error "This file is for GPU offloading compilation only" +#endif + +#include_next <time.h> + +#if __has_include(<llvm-libc-decls/time.h>) + +#if defined(__HIP__) || defined(__CUDA__) +#define __LIBC_ATTRS __attribute__((device)) +#endif + +#pragma omp begin declare target + +_Static_assert(sizeof(clock_t) == sizeof(long), "ABI mismatch!"); + +#include <llvm-libc-decls/ctype.h> + +#pragma omp end declare target + +#endif + +#endif // __CLANG_LLVM_LIBC_WRAPPERS_TIME_H__
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits