Skip to content

Commit 2220151

Browse files
committed
[flang-rt] Add Assign_omp RT call.
1 parent bd2355d commit 2220151

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

flang-rt/lib/runtime/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ set(supported_sources
2121
allocatable.cpp
2222
array-constructor.cpp
2323
assign.cpp
24+
assign_omp.cpp
2425
buffer.cpp
2526
character.cpp
2627
connection.cpp
@@ -99,6 +100,7 @@ set(gpu_sources
99100
allocatable.cpp
100101
array-constructor.cpp
101102
assign.cpp
103+
assign_omp.cpp
102104
buffer.cpp
103105
character.cpp
104106
connection.cpp
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===-- lib/runtime/assign_omp.cpp ----------------------------------*- 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+
#include "flang/Runtime/assign.h"
10+
#include "flang-rt/runtime/assign-impl.h"
11+
#include "flang-rt/runtime/derived.h"
12+
#include "flang-rt/runtime/descriptor.h"
13+
#include "flang-rt/runtime/stat.h"
14+
#include "flang-rt/runtime/terminator.h"
15+
#include "flang-rt/runtime/tools.h"
16+
#include "flang-rt/runtime/type-info.h"
17+
18+
#include <omp.h>
19+
20+
namespace Fortran::runtime {
21+
namespace omp {
22+
23+
typedef int32_t OMPDeviceTy;
24+
25+
template <typename T> static T *getDevicePtr(T *anyPtr, OMPDeviceTy ompDevice) {
26+
auto voidAnyPtr = reinterpret_cast<void *>(anyPtr);
27+
// If not present on the device it should already be a device ptr
28+
if (!omp_target_is_present(voidAnyPtr, ompDevice))
29+
return anyPtr;
30+
T *device_ptr = omp_get_mapped_ptr(anyPtr, ompDevice);
31+
return device_ptr;
32+
}
33+
34+
RT_API_ATTRS static void Assign(Descriptor &to, const Descriptor &from,
35+
Terminator &terminator, int flags, OMPDeviceTy omp_device) {
36+
std::size_t toElementBytes{to.ElementBytes()};
37+
std::size_t fromElementBytes{from.ElementBytes()};
38+
std::size_t toElements{to.Elements()};
39+
std::size_t fromElements{from.Elements()};
40+
41+
if (toElementBytes != fromElementBytes)
42+
terminator.Crash("Assign: toElementBytes != fromElementBytes");
43+
if (toElements != fromElements)
44+
terminator.Crash("Assign: toElements != fromElements");
45+
46+
// Get base addresses and calculate length
47+
void *to_base = to.raw().base_addr;
48+
void *from_base = from.raw().base_addr;
49+
size_t length = toElements * toElementBytes;
50+
51+
// Get device pointers after ensuring data is on device
52+
void *to_ptr = getDevicePtr(to_base, omp_device);
53+
void *from_ptr = getDevicePtr(from_base, omp_device);
54+
55+
// Perform copy between device pointers
56+
int result = omp_target_memcpy(to_ptr, from_ptr, length,
57+
/*dst_offset*/ 0, /*src_offset*/ 0, omp_device, omp_device);
58+
59+
if (result != 0)
60+
terminator.Crash("Assign: omp_target_memcpy failed");
61+
return;
62+
}
63+
64+
extern "C" {
65+
RT_EXT_API_GROUP_BEGIN
66+
void RTDEF(Assign_omp)(Descriptor &to, const Descriptor &from,
67+
const char *sourceFile, int sourceLine, omp::OMPDeviceTy omp_device) {
68+
Terminator terminator{sourceFile, sourceLine};
69+
Fortran::runtime::omp::Assign(to, from, terminator,
70+
MaybeReallocate | NeedFinalization | ComponentCanBeDefinedAssignment,
71+
omp_device);
72+
}
73+
74+
} // extern "C"
75+
} // namespace omp
76+
} // namespace Fortran::runtime

0 commit comments

Comments
 (0)