Warning: This file is not a C or C++ file. It does not have highlighting.
| 1 | //===-- OpenMP/Requirements.h - User required requirements -----*- C++ -*-===// |
|---|---|
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // Handling of the `omp requires` directive, e.g., requiring unified shared |
| 10 | // memory. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef OMPTARGET_OPENMP_REQUIREMENTS_H |
| 15 | #define OMPTARGET_OPENMP_REQUIREMENTS_H |
| 16 | |
| 17 | #include "Shared/Debug.h" |
| 18 | |
| 19 | #include "llvm/ADT/StringRef.h" |
| 20 | |
| 21 | #include <cassert> |
| 22 | #include <cstdint> |
| 23 | |
| 24 | enum OpenMPOffloadingRequiresDirFlags : int64_t { |
| 25 | /// flag undefined. |
| 26 | OMP_REQ_UNDEFINED = 0x000, |
| 27 | /// no requires directive present. |
| 28 | OMP_REQ_NONE = 0x001, |
| 29 | /// reverse_offload clause. |
| 30 | OMP_REQ_REVERSE_OFFLOAD = 0x002, |
| 31 | /// unified_address clause. |
| 32 | OMP_REQ_UNIFIED_ADDRESS = 0x004, |
| 33 | /// unified_shared_memory clause. |
| 34 | OMP_REQ_UNIFIED_SHARED_MEMORY = 0x008, |
| 35 | /// dynamic_allocators clause. |
| 36 | OMP_REQ_DYNAMIC_ALLOCATORS = 0x010, |
| 37 | /// Auto zero-copy extension: |
| 38 | /// when running on an APU, the GPU plugin may decide to |
| 39 | /// run in zero-copy even though the user did not program |
| 40 | /// their application with unified_shared_memory requirement. |
| 41 | OMPX_REQ_AUTO_ZERO_COPY = 0x020 |
| 42 | }; |
| 43 | |
| 44 | class RequirementCollection { |
| 45 | int64_t SetFlags = OMP_REQ_UNDEFINED; |
| 46 | |
| 47 | /// Check consistency between different requires flags (from different |
| 48 | /// translation units). |
| 49 | void checkConsistency(int64_t NewFlags, int64_t SetFlags, |
| 50 | OpenMPOffloadingRequiresDirFlags Flag, |
| 51 | llvm::StringRef Clause) { |
| 52 | if ((SetFlags & Flag) != (NewFlags & Flag)) { |
| 53 | FATAL_MESSAGE(2, "'#pragma omp requires %s' not used consistently!", |
| 54 | Clause.data()); |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | public: |
| 59 | /// Register \p NewFlags as part of the user requirements. |
| 60 | void addRequirements(int64_t NewFlags) { |
| 61 | // TODO: add more elaborate check. |
| 62 | // Minimal check: only set requires flags if previous value |
| 63 | // is undefined. This ensures that only the first call to this |
| 64 | // function will set the requires flags. All subsequent calls |
| 65 | // will be checked for compatibility. |
| 66 | assert(NewFlags != OMP_REQ_UNDEFINED && |
| 67 | "illegal undefined flag for requires directive!"); |
| 68 | if (SetFlags == OMP_REQ_UNDEFINED) { |
| 69 | SetFlags = NewFlags; |
| 70 | return; |
| 71 | } |
| 72 | |
| 73 | // Auto zero-copy is only valid when no other requirement has been set |
| 74 | // and it is computed at device initialization time, after the requirement |
| 75 | // flag has already been set to OMP_REQ_NONE. |
| 76 | if (SetFlags == OMP_REQ_NONE && NewFlags == OMPX_REQ_AUTO_ZERO_COPY) { |
| 77 | SetFlags = NewFlags; |
| 78 | return; |
| 79 | } |
| 80 | |
| 81 | // If multiple compilation units are present enforce |
| 82 | // consistency across all of them for require clauses: |
| 83 | // - reverse_offload |
| 84 | // - unified_address |
| 85 | // - unified_shared_memory |
| 86 | // - dynamic_allocators |
| 87 | checkConsistency(NewFlags, SetFlags, OMP_REQ_REVERSE_OFFLOAD, |
| 88 | "reverse_offload"); |
| 89 | checkConsistency(NewFlags, SetFlags, OMP_REQ_UNIFIED_ADDRESS, |
| 90 | "unified_address"); |
| 91 | checkConsistency(NewFlags, SetFlags, OMP_REQ_UNIFIED_SHARED_MEMORY, |
| 92 | "unified_shared_memory"); |
| 93 | checkConsistency(NewFlags, SetFlags, OMP_REQ_DYNAMIC_ALLOCATORS, |
| 94 | "dynamic_allocators"); |
| 95 | } |
| 96 | |
| 97 | /// Return the user provided requirements. |
| 98 | int64_t getRequirements() const { return SetFlags; } |
| 99 | }; |
| 100 | |
| 101 | #endif // OMPTARGET_OPENMP_DEVICE_REQUIREMENTS_H |
| 102 |
Warning: This file is not a C or C++ file. It does not have highlighting.
