llvm-capstone/flang/runtime/terminator.h
Slava Zakharin 3212051c91 [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-06-27 17:38:01 -07:00

79 lines
2.5 KiB
C++

//===-- 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/Runtime/api-attrs.h"
#include <cstdarg>
namespace Fortran::runtime {
// A mixin class for statement-specific image error termination
// for errors detected in the runtime library
class Terminator {
public:
Terminator() {}
Terminator(const Terminator &) = default;
explicit RT_API_ATTRS Terminator(
const char *sourceFileName, int sourceLine = 0)
: sourceFileName_{sourceFileName}, sourceLine_{sourceLine} {}
const char *sourceFileName() const { return sourceFileName_; }
int sourceLine() const { return sourceLine_; }
void SetLocation(const char *sourceFileName = nullptr, int sourceLine = 0) {
sourceFileName_ = sourceFileName;
sourceLine_ = sourceLine;
}
// CUDA_TODO: Clang for CUDA does not support varargs, though
// it compiles it with -fcuda-allow-variadic-functions.
// We can try to replace varargs functions with variadic templates.
[[noreturn]] RT_API_ATTRS void Crash(const char *message, ...) const;
[[noreturn]] RT_API_ATTRS void CrashArgs(
const char *message, va_list &) const;
[[noreturn]] RT_API_ATTRS void CheckFailed(
const char *predicate, const char *file, int line) const;
[[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)
void NotifyOtherImagesOfNormalEnd();
void NotifyOtherImagesOfFailImageStatement();
void NotifyOtherImagesOfErrorTermination();
} // namespace Fortran::runtime
namespace Fortran::runtime::io {
void FlushOutputOnCrash(const Terminator &);
}
#endif // FORTRAN_RUNTIME_TERMINATOR_H_