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
+
22
+ RT_API_ATTRS static void Assign (Descriptor &to, const Descriptor &from,
23
+ Terminator &terminator, int flags, int32_t omp_device) {
24
+ std::size_t toElementBytes{to.ElementBytes ()};
25
+ std::size_t fromElementBytes{from.ElementBytes ()};
26
+ std::size_t toElements{to.Elements ()};
27
+ std::size_t fromElements{from.Elements ()};
28
+
29
+ if (toElementBytes != fromElementBytes)
30
+ terminator.Crash (" Assign: toElementBytes != fromElementBytes" );
31
+ if (toElements != fromElements)
32
+ terminator.Crash (" Assign: toElements != fromElements" );
33
+
34
+ void *host_to_ptr = to.raw ().base_addr ;
35
+ void *host_from_ptr = from.raw ().base_addr ;
36
+ size_t length = toElements * toElementBytes;
37
+
38
+ printf (" assign length: %zu\n " , length);
39
+
40
+ if (!omp_target_is_present (host_to_ptr, omp_device))
41
+ terminator.Crash (" Assign: !omp_target_is_present(host_to_ptr, omp_device)" );
42
+ if (!omp_target_is_present (host_from_ptr, omp_device))
43
+ terminator.Crash (
44
+ " Assign: !omp_target_is_present(host_from_ptr, omp_device)" );
45
+
46
+ printf (" host_to_ptr: %p\n " , host_to_ptr);
47
+ #pragma omp target data use_device_ptr(host_to_ptr, host_from_ptr) device(omp_device)
48
+ {
49
+ printf (" device_to_ptr: %p\n " , host_to_ptr);
50
+ // TODO do we need to handle overlapping memory? does this function do that?
51
+ omp_target_memcpy (host_to_ptr, host_from_ptr, length, /* dst_offset*/ 0 ,
52
+ /* src_offset*/ 0 , /* dst*/ omp_device, /* src*/ omp_device);
53
+ }
54
+
55
+ return ;
56
+ }
57
+
58
+ extern " C" {
59
+ RT_EXT_API_GROUP_BEGIN
60
+ void RTDEF (Assign_omp)(Descriptor &to, const Descriptor &from,
61
+ const char *sourceFile, int sourceLine, int32_t omp_device) {
62
+ Terminator terminator{sourceFile, sourceLine};
63
+ // All top-level defined assignments can be recognized in semantics and
64
+ // will have been already been converted to calls, so don't check for
65
+ // defined assignment apart from components.
66
+ Assign (to, from, terminator,
67
+ MaybeReallocate | NeedFinalization | ComponentCanBeDefinedAssignment,
68
+ omp_device);
69
+ }
70
+ } // extern "C"
71
+
72
+ }
0 commit comments