llvm-project/flang/runtime/terminator.h

125 lines
4.0 KiB
C
Raw Normal View History

//===-- runtime/terminator.h ------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
// Termination of the image
#ifndef FORTRAN_RUNTIME_TERMINATOR_H_
#define FORTRAN_RUNTIME_TERMINATOR_H_
#include "flang/Common/api-attrs.h"
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
namespace Fortran::runtime {
// A mixin class for statement-specific image error termination
// for errors detected in the runtime library
class Terminator {
public:
RT_API_ATTRS Terminator() {}
Terminator(const Terminator &) = default;
[RFC][flang] Experimental device build of Flang runtime. These are initial changes to experiment with building the Fortran runtime as a CUDA or OpenMP target offload library. The initial patch defines a set of macros that have to be used consistently in Flang runtime source code so that it can be built for different offload devices using different programming models (CUDA, HIP, OpenMP target offload). Currently supported modes are: * CUDA: Flang runtime may be built as a fatlib for the host and a set of CUDA architectures specified during the build. The packaging of the device code is done by the CUDA toolchain and may differ from toolchan to toolchain. * OpenMP offload: - host_device mode: Flang runtime may be built as a fatlib for the host and a set of OpenMP offload architectures. The packaging of the device code is done by the OpenMP offload compiler and may differ from compiler to compiler. OpenMP offload 'nohost' mode is a TODO to match the build setup of libomptarget/DeviceRTL. Flang runtime will be built as LLVM Bitcode library using Clang/LLVM toolchain. The host part of the library will be "empty", so there will be two distributable object: the host Flang runtime and dummy host library with device Flang runtime pieces packaged using clang-offload-packager and clang. In all supported modes, enabling parts of Flang runtime for the device compilation can be done iteratively to make the patches observable. Note that at any point in time the resulting library may have unresolved references to not yet enabled parts of Flang runtime. Example cmake/make commands for building with Clang for NVPTX target: cmake \ -DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \ -DCMAKE_CUDA_ARCHITECTURES=80 \ -DCMAKE_C_COMPILER=/clang_nvptx/bin/clang \ -DCMAKE_CXX_COMPILER=/clang_nvptx/bin/clang++ \ -DCMAKE_CUDA_COMPILER=/clang_nvptx/bin/clang \ /llvm-project/flang/runtime/ make -j FortranRuntime Example cmake/make commands for building with Clang OpenMP offload: cmake \ -DFLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD="host_device" \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DFLANG_OMP_DEVICE_ARCHITECTURES="sm_80" \ ../flang/runtime/ make -j FortranRuntime Differential Revision: https://reviews.llvm.org/D151173
2023-05-22 14:05:18 -07:00
explicit RT_API_ATTRS Terminator(
const char *sourceFileName, int sourceLine = 0)
: sourceFileName_{sourceFileName}, sourceLine_{sourceLine} {}
RT_API_ATTRS const char *sourceFileName() const { return sourceFileName_; }
RT_API_ATTRS int sourceLine() const { return sourceLine_; }
RT_API_ATTRS void SetLocation(
const char *sourceFileName = nullptr, int sourceLine = 0) {
sourceFileName_ = sourceFileName;
sourceLine_ = sourceLine;
}
[RFC][flang] Experimental device build of Flang runtime. These are initial changes to experiment with building the Fortran runtime as a CUDA or OpenMP target offload library. The initial patch defines a set of macros that have to be used consistently in Flang runtime source code so that it can be built for different offload devices using different programming models (CUDA, HIP, OpenMP target offload). Currently supported modes are: * CUDA: Flang runtime may be built as a fatlib for the host and a set of CUDA architectures specified during the build. The packaging of the device code is done by the CUDA toolchain and may differ from toolchan to toolchain. * OpenMP offload: - host_device mode: Flang runtime may be built as a fatlib for the host and a set of OpenMP offload architectures. The packaging of the device code is done by the OpenMP offload compiler and may differ from compiler to compiler. OpenMP offload 'nohost' mode is a TODO to match the build setup of libomptarget/DeviceRTL. Flang runtime will be built as LLVM Bitcode library using Clang/LLVM toolchain. The host part of the library will be "empty", so there will be two distributable object: the host Flang runtime and dummy host library with device Flang runtime pieces packaged using clang-offload-packager and clang. In all supported modes, enabling parts of Flang runtime for the device compilation can be done iteratively to make the patches observable. Note that at any point in time the resulting library may have unresolved references to not yet enabled parts of Flang runtime. Example cmake/make commands for building with Clang for NVPTX target: cmake \ -DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \ -DCMAKE_CUDA_ARCHITECTURES=80 \ -DCMAKE_C_COMPILER=/clang_nvptx/bin/clang \ -DCMAKE_CXX_COMPILER=/clang_nvptx/bin/clang++ \ -DCMAKE_CUDA_COMPILER=/clang_nvptx/bin/clang \ /llvm-project/flang/runtime/ make -j FortranRuntime Example cmake/make commands for building with Clang OpenMP offload: cmake \ -DFLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD="host_device" \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DFLANG_OMP_DEVICE_ARCHITECTURES="sm_80" \ ../flang/runtime/ make -j FortranRuntime Differential Revision: https://reviews.llvm.org/D151173
2023-05-22 14:05:18 -07:00
// Silence compiler warnings about the format string being
// non-literal. A more precise control would be
// __attribute__((format_arg(2))), but it requires the function
// to return 'char *', which does not work well with noreturn.
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
// Device offload compilers do not normally support varargs and va_list,
// so use C++ variadic templates to forward the crash arguments
// to regular printf for the device compilation.
// Try to keep the inline implementations as small as possible.
template <typename... Args>
[[noreturn]] RT_DEVICE_NOINLINE RT_API_ATTRS const char *Crash(
const char *message, Args... args) const {
#if !defined(RT_DEVICE_COMPILATION)
// Invoke handler set up by the test harness.
InvokeCrashHandler(message, args...);
#endif
CrashHeader();
PrintCrashArgs(message, args...);
CrashFooter();
}
template <typename... Args>
RT_API_ATTRS void PrintCrashArgs(const char *message, Args... args) const {
#if defined(RT_DEVICE_COMPILATION)
std::printf(message, args...);
#else
std::fprintf(stderr, message, args...);
#endif
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
RT_API_ATTRS void CrashHeader() const;
[[noreturn]] RT_API_ATTRS void CrashFooter() const;
#if !defined(RT_DEVICE_COMPILATION)
void InvokeCrashHandler(const char *message, ...) const;
[[noreturn]] void CrashArgs(const char *message, va_list &) const;
#endif
[RFC][flang] Experimental device build of Flang runtime. These are initial changes to experiment with building the Fortran runtime as a CUDA or OpenMP target offload library. The initial patch defines a set of macros that have to be used consistently in Flang runtime source code so that it can be built for different offload devices using different programming models (CUDA, HIP, OpenMP target offload). Currently supported modes are: * CUDA: Flang runtime may be built as a fatlib for the host and a set of CUDA architectures specified during the build. The packaging of the device code is done by the CUDA toolchain and may differ from toolchan to toolchain. * OpenMP offload: - host_device mode: Flang runtime may be built as a fatlib for the host and a set of OpenMP offload architectures. The packaging of the device code is done by the OpenMP offload compiler and may differ from compiler to compiler. OpenMP offload 'nohost' mode is a TODO to match the build setup of libomptarget/DeviceRTL. Flang runtime will be built as LLVM Bitcode library using Clang/LLVM toolchain. The host part of the library will be "empty", so there will be two distributable object: the host Flang runtime and dummy host library with device Flang runtime pieces packaged using clang-offload-packager and clang. In all supported modes, enabling parts of Flang runtime for the device compilation can be done iteratively to make the patches observable. Note that at any point in time the resulting library may have unresolved references to not yet enabled parts of Flang runtime. Example cmake/make commands for building with Clang for NVPTX target: cmake \ -DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \ -DCMAKE_CUDA_ARCHITECTURES=80 \ -DCMAKE_C_COMPILER=/clang_nvptx/bin/clang \ -DCMAKE_CXX_COMPILER=/clang_nvptx/bin/clang++ \ -DCMAKE_CUDA_COMPILER=/clang_nvptx/bin/clang \ /llvm-project/flang/runtime/ make -j FortranRuntime Example cmake/make commands for building with Clang OpenMP offload: cmake \ -DFLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD="host_device" \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DFLANG_OMP_DEVICE_ARCHITECTURES="sm_80" \ ../flang/runtime/ make -j FortranRuntime Differential Revision: https://reviews.llvm.org/D151173
2023-05-22 14:05:18 -07:00
[[noreturn]] RT_API_ATTRS void CheckFailed(
const char *predicate, const char *file, int line) const;
[RFC][flang] Experimental device build of Flang runtime. These are initial changes to experiment with building the Fortran runtime as a CUDA or OpenMP target offload library. The initial patch defines a set of macros that have to be used consistently in Flang runtime source code so that it can be built for different offload devices using different programming models (CUDA, HIP, OpenMP target offload). Currently supported modes are: * CUDA: Flang runtime may be built as a fatlib for the host and a set of CUDA architectures specified during the build. The packaging of the device code is done by the CUDA toolchain and may differ from toolchan to toolchain. * OpenMP offload: - host_device mode: Flang runtime may be built as a fatlib for the host and a set of OpenMP offload architectures. The packaging of the device code is done by the OpenMP offload compiler and may differ from compiler to compiler. OpenMP offload 'nohost' mode is a TODO to match the build setup of libomptarget/DeviceRTL. Flang runtime will be built as LLVM Bitcode library using Clang/LLVM toolchain. The host part of the library will be "empty", so there will be two distributable object: the host Flang runtime and dummy host library with device Flang runtime pieces packaged using clang-offload-packager and clang. In all supported modes, enabling parts of Flang runtime for the device compilation can be done iteratively to make the patches observable. Note that at any point in time the resulting library may have unresolved references to not yet enabled parts of Flang runtime. Example cmake/make commands for building with Clang for NVPTX target: cmake \ -DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \ -DCMAKE_CUDA_ARCHITECTURES=80 \ -DCMAKE_C_COMPILER=/clang_nvptx/bin/clang \ -DCMAKE_CXX_COMPILER=/clang_nvptx/bin/clang++ \ -DCMAKE_CUDA_COMPILER=/clang_nvptx/bin/clang \ /llvm-project/flang/runtime/ make -j FortranRuntime Example cmake/make commands for building with Clang OpenMP offload: cmake \ -DFLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD="host_device" \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DFLANG_OMP_DEVICE_ARCHITECTURES="sm_80" \ ../flang/runtime/ make -j FortranRuntime Differential Revision: https://reviews.llvm.org/D151173
2023-05-22 14:05:18 -07:00
[[noreturn]] RT_API_ATTRS void CheckFailed(const char *predicate) const;
// For test harnessing - overrides CrashArgs().
static void RegisterCrashHandler(void (*)(const char *sourceFile,
int sourceLine, const char *message, va_list &ap));
private:
const char *sourceFileName_{nullptr};
int sourceLine_{0};
};
// RUNTIME_CHECK() guarantees evaluation of its predicate.
#define RUNTIME_CHECK(terminator, pred) \
if (pred) \
; \
else \
(terminator).CheckFailed(#pred, __FILE__, __LINE__)
#define INTERNAL_CHECK(pred) \
if (pred) \
; \
else \
Terminator{__FILE__, __LINE__}.CheckFailed(#pred)
RT_API_ATTRS void NotifyOtherImagesOfNormalEnd();
RT_API_ATTRS void NotifyOtherImagesOfFailImageStatement();
RT_API_ATTRS void NotifyOtherImagesOfErrorTermination();
} // namespace Fortran::runtime
namespace Fortran::runtime::io {
RT_API_ATTRS void FlushOutputOnCrash(const Terminator &);
}
#endif // FORTRAN_RUNTIME_TERMINATOR_H_