167ab875fSJohannes Doerfert //===----- Workshare.cpp -  OpenMP workshare implementation ------ C++ -*-===//
267ab875fSJohannes Doerfert //
367ab875fSJohannes Doerfert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
467ab875fSJohannes Doerfert // See https://llvm.org/LICENSE.txt for license information.
567ab875fSJohannes Doerfert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
667ab875fSJohannes Doerfert //
767ab875fSJohannes Doerfert //===----------------------------------------------------------------------===//
867ab875fSJohannes Doerfert //
967ab875fSJohannes Doerfert // This file contains the implementation of the KMPC interface
1067ab875fSJohannes Doerfert // for the loop construct plus other worksharing constructs that use the same
1167ab875fSJohannes Doerfert // interface as loops.
1267ab875fSJohannes Doerfert //
1367ab875fSJohannes Doerfert //===----------------------------------------------------------------------===//
1467ab875fSJohannes Doerfert 
1567ab875fSJohannes Doerfert #include "Debug.h"
1667ab875fSJohannes Doerfert #include "Interface.h"
1767ab875fSJohannes Doerfert #include "Mapping.h"
1867ab875fSJohannes Doerfert #include "State.h"
1967ab875fSJohannes Doerfert #include "Synchronization.h"
2067ab875fSJohannes Doerfert #include "Types.h"
2167ab875fSJohannes Doerfert #include "Utils.h"
2267ab875fSJohannes Doerfert 
2367ab875fSJohannes Doerfert using namespace _OMP;
2467ab875fSJohannes Doerfert 
2567ab875fSJohannes Doerfert // TODO:
2667ab875fSJohannes Doerfert struct DynamicScheduleTracker {
2767ab875fSJohannes Doerfert   int64_t Chunk;
2867ab875fSJohannes Doerfert   int64_t LoopUpperBound;
2967ab875fSJohannes Doerfert   int64_t NextLowerBound;
3067ab875fSJohannes Doerfert   int64_t Stride;
3167ab875fSJohannes Doerfert   kmp_sched_t ScheduleType;
3267ab875fSJohannes Doerfert   DynamicScheduleTracker *NextDST;
3367ab875fSJohannes Doerfert };
3467ab875fSJohannes Doerfert 
3567ab875fSJohannes Doerfert #define ASSERT0(...)
3667ab875fSJohannes Doerfert 
3767ab875fSJohannes Doerfert // used by the library for the interface with the app
3867ab875fSJohannes Doerfert #define DISPATCH_FINISHED 0
3967ab875fSJohannes Doerfert #define DISPATCH_NOTFINISHED 1
4067ab875fSJohannes Doerfert 
4167ab875fSJohannes Doerfert // used by dynamic scheduling
4267ab875fSJohannes Doerfert #define FINISHED 0
4367ab875fSJohannes Doerfert #define NOT_FINISHED 1
4467ab875fSJohannes Doerfert #define LAST_CHUNK 2
4567ab875fSJohannes Doerfert 
46b4f8443dSJoseph Huber #pragma omp begin declare target device_type(nohost)
4767ab875fSJohannes Doerfert 
4867ab875fSJohannes Doerfert // TODO: This variable is a hack inherited from the old runtime.
494863fed9SJoseph Huber static uint64_t SHARED(Cnt);
5067ab875fSJohannes Doerfert 
5167ab875fSJohannes Doerfert template <typename T, typename ST> struct omptarget_nvptx_LoopSupport {
5267ab875fSJohannes Doerfert   ////////////////////////////////////////////////////////////////////////////////
5367ab875fSJohannes Doerfert   // Loop with static scheduling with chunk
5467ab875fSJohannes Doerfert 
5567ab875fSJohannes Doerfert   // Generic implementation of OMP loop scheduling with static policy
5667ab875fSJohannes Doerfert   /*! \brief Calculate initial bounds for static loop and stride
5767ab875fSJohannes Doerfert    *  @param[in] loc location in code of the call (not used here)
5867ab875fSJohannes Doerfert    *  @param[in] global_tid global thread id
5967ab875fSJohannes Doerfert    *  @param[in] schetype type of scheduling (see omptarget-nvptx.h)
6067ab875fSJohannes Doerfert    *  @param[in] plastiter pointer to last iteration
6167ab875fSJohannes Doerfert    *  @param[in,out] pointer to loop lower bound. it will contain value of
6267ab875fSJohannes Doerfert    *  lower bound of first chunk
6367ab875fSJohannes Doerfert    *  @param[in,out] pointer to loop upper bound. It will contain value of
6467ab875fSJohannes Doerfert    *  upper bound of first chunk
6567ab875fSJohannes Doerfert    *  @param[in,out] pointer to loop stride. It will contain value of stride
6667ab875fSJohannes Doerfert    *  between two successive chunks executed by the same thread
6767ab875fSJohannes Doerfert    *  @param[in] loop increment bump
6867ab875fSJohannes Doerfert    *  @param[in] chunk size
6967ab875fSJohannes Doerfert    */
7067ab875fSJohannes Doerfert 
7167ab875fSJohannes Doerfert   // helper function for static chunk
ForStaticChunkomptarget_nvptx_LoopSupport7267ab875fSJohannes Doerfert   static void ForStaticChunk(int &last, T &lb, T &ub, ST &stride, ST chunk,
7367ab875fSJohannes Doerfert                              T entityId, T numberOfEntities) {
7467ab875fSJohannes Doerfert     // each thread executes multiple chunks all of the same size, except
7567ab875fSJohannes Doerfert     // the last one
7667ab875fSJohannes Doerfert     // distance between two successive chunks
7767ab875fSJohannes Doerfert     stride = numberOfEntities * chunk;
7867ab875fSJohannes Doerfert     lb = lb + entityId * chunk;
7967ab875fSJohannes Doerfert     T inputUb = ub;
8067ab875fSJohannes Doerfert     ub = lb + chunk - 1; // Clang uses i <= ub
8167ab875fSJohannes Doerfert     // Say ub' is the begining of the last chunk. Then who ever has a
8267ab875fSJohannes Doerfert     // lower bound plus a multiple of the increment equal to ub' is
8367ab875fSJohannes Doerfert     // the last one.
8467ab875fSJohannes Doerfert     T beginingLastChunk = inputUb - (inputUb % chunk);
8567ab875fSJohannes Doerfert     last = ((beginingLastChunk - lb) % stride) == 0;
8667ab875fSJohannes Doerfert   }
8767ab875fSJohannes Doerfert 
8867ab875fSJohannes Doerfert   ////////////////////////////////////////////////////////////////////////////////
8967ab875fSJohannes Doerfert   // Loop with static scheduling without chunk
9067ab875fSJohannes Doerfert 
9167ab875fSJohannes Doerfert   // helper function for static no chunk
ForStaticNoChunkomptarget_nvptx_LoopSupport9267ab875fSJohannes Doerfert   static void ForStaticNoChunk(int &last, T &lb, T &ub, ST &stride, ST &chunk,
9367ab875fSJohannes Doerfert                                T entityId, T numberOfEntities) {
9467ab875fSJohannes Doerfert     // No chunk size specified.  Each thread or warp gets at most one
9567ab875fSJohannes Doerfert     // chunk; chunks are all almost of equal size
9667ab875fSJohannes Doerfert     T loopSize = ub - lb + 1;
9767ab875fSJohannes Doerfert 
9867ab875fSJohannes Doerfert     chunk = loopSize / numberOfEntities;
9967ab875fSJohannes Doerfert     T leftOver = loopSize - chunk * numberOfEntities;
10067ab875fSJohannes Doerfert 
10167ab875fSJohannes Doerfert     if (entityId < leftOver) {
10267ab875fSJohannes Doerfert       chunk++;
10367ab875fSJohannes Doerfert       lb = lb + entityId * chunk;
10467ab875fSJohannes Doerfert     } else {
10567ab875fSJohannes Doerfert       lb = lb + entityId * chunk + leftOver;
10667ab875fSJohannes Doerfert     }
10767ab875fSJohannes Doerfert 
10867ab875fSJohannes Doerfert     T inputUb = ub;
10967ab875fSJohannes Doerfert     ub = lb + chunk - 1; // Clang uses i <= ub
11067ab875fSJohannes Doerfert     last = lb <= inputUb && inputUb <= ub;
11167ab875fSJohannes Doerfert     stride = loopSize; // make sure we only do 1 chunk per warp
11267ab875fSJohannes Doerfert   }
11367ab875fSJohannes Doerfert 
11467ab875fSJohannes Doerfert   ////////////////////////////////////////////////////////////////////////////////
11567ab875fSJohannes Doerfert   // Support for Static Init
11667ab875fSJohannes Doerfert 
for_static_initomptarget_nvptx_LoopSupport117ef922c69SJohannes Doerfert   static void for_static_init(int32_t, int32_t schedtype,
11867ab875fSJohannes Doerfert                               int32_t *plastiter, T *plower, T *pupper,
11967ab875fSJohannes Doerfert                               ST *pstride, ST chunk, bool IsSPMDExecutionMode) {
120ef922c69SJohannes Doerfert     int32_t gtid = omp_get_thread_num();
12167ab875fSJohannes Doerfert     int numberOfActiveOMPThreads = omp_get_num_threads();
12267ab875fSJohannes Doerfert 
12367ab875fSJohannes Doerfert     // All warps that are in excess of the maximum requested, do
12467ab875fSJohannes Doerfert     // not execute the loop
12567ab875fSJohannes Doerfert     ASSERT0(LT_FUSSY, gtid < numberOfActiveOMPThreads,
12667ab875fSJohannes Doerfert             "current thread is not needed here; error");
12767ab875fSJohannes Doerfert 
12867ab875fSJohannes Doerfert     // copy
12967ab875fSJohannes Doerfert     int lastiter = 0;
13067ab875fSJohannes Doerfert     T lb = *plower;
13167ab875fSJohannes Doerfert     T ub = *pupper;
13267ab875fSJohannes Doerfert     ST stride = *pstride;
13367ab875fSJohannes Doerfert 
13467ab875fSJohannes Doerfert     // init
13567ab875fSJohannes Doerfert     switch (SCHEDULE_WITHOUT_MODIFIERS(schedtype)) {
13667ab875fSJohannes Doerfert     case kmp_sched_static_chunk: {
13767ab875fSJohannes Doerfert       if (chunk > 0) {
13867ab875fSJohannes Doerfert         ForStaticChunk(lastiter, lb, ub, stride, chunk, gtid,
13967ab875fSJohannes Doerfert                        numberOfActiveOMPThreads);
14067ab875fSJohannes Doerfert         break;
14167ab875fSJohannes Doerfert       }
142*ce0caf41SJoseph Huber       [[fallthrough]];
14367ab875fSJohannes Doerfert     } // note: if chunk <=0, use nochunk
14467ab875fSJohannes Doerfert     case kmp_sched_static_balanced_chunk: {
14567ab875fSJohannes Doerfert       if (chunk > 0) {
14667ab875fSJohannes Doerfert         // round up to make sure the chunk is enough to cover all iterations
14767ab875fSJohannes Doerfert         T tripCount = ub - lb + 1; // +1 because ub is inclusive
14867ab875fSJohannes Doerfert         T span = (tripCount + numberOfActiveOMPThreads - 1) /
14967ab875fSJohannes Doerfert                  numberOfActiveOMPThreads;
15067ab875fSJohannes Doerfert         // perform chunk adjustment
15167ab875fSJohannes Doerfert         chunk = (span + chunk - 1) & ~(chunk - 1);
15267ab875fSJohannes Doerfert 
15367ab875fSJohannes Doerfert         ASSERT0(LT_FUSSY, ub >= lb, "ub must be >= lb.");
15467ab875fSJohannes Doerfert         T oldUb = ub;
15567ab875fSJohannes Doerfert         ForStaticChunk(lastiter, lb, ub, stride, chunk, gtid,
15667ab875fSJohannes Doerfert                        numberOfActiveOMPThreads);
15767ab875fSJohannes Doerfert         if (ub > oldUb)
15867ab875fSJohannes Doerfert           ub = oldUb;
15967ab875fSJohannes Doerfert         break;
16067ab875fSJohannes Doerfert       }
161*ce0caf41SJoseph Huber       [[fallthrough]];
16267ab875fSJohannes Doerfert     } // note: if chunk <=0, use nochunk
16367ab875fSJohannes Doerfert     case kmp_sched_static_nochunk: {
16467ab875fSJohannes Doerfert       ForStaticNoChunk(lastiter, lb, ub, stride, chunk, gtid,
16567ab875fSJohannes Doerfert                        numberOfActiveOMPThreads);
16667ab875fSJohannes Doerfert       break;
16767ab875fSJohannes Doerfert     }
16867ab875fSJohannes Doerfert     case kmp_sched_distr_static_chunk: {
16967ab875fSJohannes Doerfert       if (chunk > 0) {
17067ab875fSJohannes Doerfert         ForStaticChunk(lastiter, lb, ub, stride, chunk, omp_get_team_num(),
17167ab875fSJohannes Doerfert                        omp_get_num_teams());
17267ab875fSJohannes Doerfert         break;
17367ab875fSJohannes Doerfert       }
174*ce0caf41SJoseph Huber       [[fallthrough]];
175*ce0caf41SJoseph Huber     } // note: if chunk <=0, use nochunk
17667ab875fSJohannes Doerfert     case kmp_sched_distr_static_nochunk: {
17767ab875fSJohannes Doerfert       ForStaticNoChunk(lastiter, lb, ub, stride, chunk, omp_get_team_num(),
17867ab875fSJohannes Doerfert                        omp_get_num_teams());
17967ab875fSJohannes Doerfert       break;
18067ab875fSJohannes Doerfert     }
18167ab875fSJohannes Doerfert     case kmp_sched_distr_static_chunk_sched_static_chunkone: {
18267ab875fSJohannes Doerfert       ForStaticChunk(lastiter, lb, ub, stride, chunk,
18367ab875fSJohannes Doerfert                      numberOfActiveOMPThreads * omp_get_team_num() + gtid,
18467ab875fSJohannes Doerfert                      omp_get_num_teams() * numberOfActiveOMPThreads);
18567ab875fSJohannes Doerfert       break;
18667ab875fSJohannes Doerfert     }
18767ab875fSJohannes Doerfert     default: {
18867ab875fSJohannes Doerfert       // ASSERT(LT_FUSSY, 0, "unknown schedtype %d", (int)schedtype);
18967ab875fSJohannes Doerfert       ForStaticChunk(lastiter, lb, ub, stride, chunk, gtid,
19067ab875fSJohannes Doerfert                      numberOfActiveOMPThreads);
19167ab875fSJohannes Doerfert       break;
19267ab875fSJohannes Doerfert     }
19367ab875fSJohannes Doerfert     }
19467ab875fSJohannes Doerfert     // copy back
19567ab875fSJohannes Doerfert     *plastiter = lastiter;
19667ab875fSJohannes Doerfert     *plower = lb;
19767ab875fSJohannes Doerfert     *pupper = ub;
19867ab875fSJohannes Doerfert     *pstride = stride;
19967ab875fSJohannes Doerfert   }
20067ab875fSJohannes Doerfert 
20167ab875fSJohannes Doerfert   ////////////////////////////////////////////////////////////////////////////////
20267ab875fSJohannes Doerfert   // Support for dispatch Init
20367ab875fSJohannes Doerfert 
OrderedScheduleomptarget_nvptx_LoopSupport20467ab875fSJohannes Doerfert   static int OrderedSchedule(kmp_sched_t schedule) {
20567ab875fSJohannes Doerfert     return schedule >= kmp_sched_ordered_first &&
20667ab875fSJohannes Doerfert            schedule <= kmp_sched_ordered_last;
20767ab875fSJohannes Doerfert   }
20867ab875fSJohannes Doerfert 
dispatch_initomptarget_nvptx_LoopSupport20967ab875fSJohannes Doerfert   static void dispatch_init(IdentTy *loc, int32_t threadId,
21067ab875fSJohannes Doerfert                             kmp_sched_t schedule, T lb, T ub, ST st, ST chunk,
21167ab875fSJohannes Doerfert                             DynamicScheduleTracker *DST) {
21267ab875fSJohannes Doerfert     int tid = mapping::getThreadIdInBlock();
21367ab875fSJohannes Doerfert     T tnum = omp_get_num_threads();
21467ab875fSJohannes Doerfert     T tripCount = ub - lb + 1; // +1 because ub is inclusive
21567ab875fSJohannes Doerfert     ASSERT0(LT_FUSSY, threadId < tnum,
21667ab875fSJohannes Doerfert             "current thread is not needed here; error");
21767ab875fSJohannes Doerfert 
21867ab875fSJohannes Doerfert     /* Currently just ignore the monotonic and non-monotonic modifiers
21967ab875fSJohannes Doerfert      * (the compiler isn't producing them * yet anyway).
22067ab875fSJohannes Doerfert      * When it is we'll want to look at them somewhere here and use that
22167ab875fSJohannes Doerfert      * information to add to our schedule choice. We shouldn't need to pass
22267ab875fSJohannes Doerfert      * them on, they merely affect which schedule we can legally choose for
22367ab875fSJohannes Doerfert      * various dynamic cases. (In particular, whether or not a stealing scheme
22467ab875fSJohannes Doerfert      * is legal).
22567ab875fSJohannes Doerfert      */
22667ab875fSJohannes Doerfert     schedule = SCHEDULE_WITHOUT_MODIFIERS(schedule);
22767ab875fSJohannes Doerfert 
22867ab875fSJohannes Doerfert     // Process schedule.
22967ab875fSJohannes Doerfert     if (tnum == 1 || tripCount <= 1 || OrderedSchedule(schedule)) {
23067ab875fSJohannes Doerfert       if (OrderedSchedule(schedule))
23167ab875fSJohannes Doerfert         __kmpc_barrier(loc, threadId);
23267ab875fSJohannes Doerfert       schedule = kmp_sched_static_chunk;
23367ab875fSJohannes Doerfert       chunk = tripCount; // one thread gets the whole loop
23467ab875fSJohannes Doerfert     } else if (schedule == kmp_sched_runtime) {
23567ab875fSJohannes Doerfert       // process runtime
23667ab875fSJohannes Doerfert       omp_sched_t rtSched;
23767ab875fSJohannes Doerfert       int ChunkInt;
23867ab875fSJohannes Doerfert       omp_get_schedule(&rtSched, &ChunkInt);
23967ab875fSJohannes Doerfert       chunk = ChunkInt;
24067ab875fSJohannes Doerfert       switch (rtSched) {
24167ab875fSJohannes Doerfert       case omp_sched_static: {
24267ab875fSJohannes Doerfert         if (chunk > 0)
24367ab875fSJohannes Doerfert           schedule = kmp_sched_static_chunk;
24467ab875fSJohannes Doerfert         else
24567ab875fSJohannes Doerfert           schedule = kmp_sched_static_nochunk;
24667ab875fSJohannes Doerfert         break;
24767ab875fSJohannes Doerfert       }
24867ab875fSJohannes Doerfert       case omp_sched_auto: {
24967ab875fSJohannes Doerfert         schedule = kmp_sched_static_chunk;
25067ab875fSJohannes Doerfert         chunk = 1;
25167ab875fSJohannes Doerfert         break;
25267ab875fSJohannes Doerfert       }
25367ab875fSJohannes Doerfert       case omp_sched_dynamic:
25467ab875fSJohannes Doerfert       case omp_sched_guided: {
25567ab875fSJohannes Doerfert         schedule = kmp_sched_dynamic;
25667ab875fSJohannes Doerfert         break;
25767ab875fSJohannes Doerfert       }
25867ab875fSJohannes Doerfert       }
25967ab875fSJohannes Doerfert     } else if (schedule == kmp_sched_auto) {
26067ab875fSJohannes Doerfert       schedule = kmp_sched_static_chunk;
26167ab875fSJohannes Doerfert       chunk = 1;
26267ab875fSJohannes Doerfert     } else {
26367ab875fSJohannes Doerfert       // ASSERT(LT_FUSSY,
26467ab875fSJohannes Doerfert       //        schedule == kmp_sched_dynamic || schedule == kmp_sched_guided,
26567ab875fSJohannes Doerfert       //        "unknown schedule %d & chunk %lld\n", (int)schedule,
26667ab875fSJohannes Doerfert       //        (long long)chunk);
26767ab875fSJohannes Doerfert     }
26867ab875fSJohannes Doerfert 
26967ab875fSJohannes Doerfert     // init schedules
27067ab875fSJohannes Doerfert     if (schedule == kmp_sched_static_chunk) {
27167ab875fSJohannes Doerfert       ASSERT0(LT_FUSSY, chunk > 0, "bad chunk value");
27267ab875fSJohannes Doerfert       // save sched state
27367ab875fSJohannes Doerfert       DST->ScheduleType = schedule;
27467ab875fSJohannes Doerfert       // save ub
27567ab875fSJohannes Doerfert       DST->LoopUpperBound = ub;
27667ab875fSJohannes Doerfert       // compute static chunk
27767ab875fSJohannes Doerfert       ST stride;
27867ab875fSJohannes Doerfert       int lastiter = 0;
27967ab875fSJohannes Doerfert       ForStaticChunk(lastiter, lb, ub, stride, chunk, threadId, tnum);
28067ab875fSJohannes Doerfert       // save computed params
28167ab875fSJohannes Doerfert       DST->Chunk = chunk;
28267ab875fSJohannes Doerfert       DST->NextLowerBound = lb;
28367ab875fSJohannes Doerfert       DST->Stride = stride;
28467ab875fSJohannes Doerfert     } else if (schedule == kmp_sched_static_balanced_chunk) {
28567ab875fSJohannes Doerfert       ASSERT0(LT_FUSSY, chunk > 0, "bad chunk value");
28667ab875fSJohannes Doerfert       // save sched state
28767ab875fSJohannes Doerfert       DST->ScheduleType = schedule;
28867ab875fSJohannes Doerfert       // save ub
28967ab875fSJohannes Doerfert       DST->LoopUpperBound = ub;
29067ab875fSJohannes Doerfert       // compute static chunk
29167ab875fSJohannes Doerfert       ST stride;
29267ab875fSJohannes Doerfert       int lastiter = 0;
29367ab875fSJohannes Doerfert       // round up to make sure the chunk is enough to cover all iterations
29467ab875fSJohannes Doerfert       T span = (tripCount + tnum - 1) / tnum;
29567ab875fSJohannes Doerfert       // perform chunk adjustment
29667ab875fSJohannes Doerfert       chunk = (span + chunk - 1) & ~(chunk - 1);
29767ab875fSJohannes Doerfert 
29867ab875fSJohannes Doerfert       T oldUb = ub;
29967ab875fSJohannes Doerfert       ForStaticChunk(lastiter, lb, ub, stride, chunk, threadId, tnum);
30067ab875fSJohannes Doerfert       ASSERT0(LT_FUSSY, ub >= lb, "ub must be >= lb.");
30167ab875fSJohannes Doerfert       if (ub > oldUb)
30267ab875fSJohannes Doerfert         ub = oldUb;
30367ab875fSJohannes Doerfert       // save computed params
30467ab875fSJohannes Doerfert       DST->Chunk = chunk;
30567ab875fSJohannes Doerfert       DST->NextLowerBound = lb;
30667ab875fSJohannes Doerfert       DST->Stride = stride;
30767ab875fSJohannes Doerfert     } else if (schedule == kmp_sched_static_nochunk) {
30867ab875fSJohannes Doerfert       ASSERT0(LT_FUSSY, chunk == 0, "bad chunk value");
30967ab875fSJohannes Doerfert       // save sched state
31067ab875fSJohannes Doerfert       DST->ScheduleType = schedule;
31167ab875fSJohannes Doerfert       // save ub
31267ab875fSJohannes Doerfert       DST->LoopUpperBound = ub;
31367ab875fSJohannes Doerfert       // compute static chunk
31467ab875fSJohannes Doerfert       ST stride;
31567ab875fSJohannes Doerfert       int lastiter = 0;
31667ab875fSJohannes Doerfert       ForStaticNoChunk(lastiter, lb, ub, stride, chunk, threadId, tnum);
31767ab875fSJohannes Doerfert       // save computed params
31867ab875fSJohannes Doerfert       DST->Chunk = chunk;
31967ab875fSJohannes Doerfert       DST->NextLowerBound = lb;
32067ab875fSJohannes Doerfert       DST->Stride = stride;
32167ab875fSJohannes Doerfert     } else if (schedule == kmp_sched_dynamic || schedule == kmp_sched_guided) {
32267ab875fSJohannes Doerfert       // save data
32367ab875fSJohannes Doerfert       DST->ScheduleType = schedule;
32467ab875fSJohannes Doerfert       if (chunk < 1)
32567ab875fSJohannes Doerfert         chunk = 1;
32667ab875fSJohannes Doerfert       DST->Chunk = chunk;
32767ab875fSJohannes Doerfert       DST->LoopUpperBound = ub;
32867ab875fSJohannes Doerfert       DST->NextLowerBound = lb;
32967ab875fSJohannes Doerfert       __kmpc_barrier(loc, threadId);
33067ab875fSJohannes Doerfert       if (tid == 0) {
33167ab875fSJohannes Doerfert         Cnt = 0;
33267ab875fSJohannes Doerfert         fence::team(__ATOMIC_SEQ_CST);
33367ab875fSJohannes Doerfert       }
33467ab875fSJohannes Doerfert       __kmpc_barrier(loc, threadId);
33567ab875fSJohannes Doerfert     }
33667ab875fSJohannes Doerfert   }
33767ab875fSJohannes Doerfert 
33867ab875fSJohannes Doerfert   ////////////////////////////////////////////////////////////////////////////////
33967ab875fSJohannes Doerfert   // Support for dispatch next
34067ab875fSJohannes Doerfert 
NextIteromptarget_nvptx_LoopSupport34167ab875fSJohannes Doerfert   static uint64_t NextIter() {
34267ab875fSJohannes Doerfert     __kmpc_impl_lanemask_t active = mapping::activemask();
34367ab875fSJohannes Doerfert     uint32_t leader = utils::ffs(active) - 1;
34467ab875fSJohannes Doerfert     uint32_t change = utils::popc(active);
34567ab875fSJohannes Doerfert     __kmpc_impl_lanemask_t lane_mask_lt = mapping::lanemaskLT();
34667ab875fSJohannes Doerfert     unsigned int rank = utils::popc(active & lane_mask_lt);
347*ce0caf41SJoseph Huber     uint64_t warp_res = 0;
34867ab875fSJohannes Doerfert     if (rank == 0) {
34967ab875fSJohannes Doerfert       warp_res = atomic::add(&Cnt, change, __ATOMIC_SEQ_CST);
35067ab875fSJohannes Doerfert     }
35167ab875fSJohannes Doerfert     warp_res = utils::shuffle(active, warp_res, leader);
35267ab875fSJohannes Doerfert     return warp_res + rank;
35367ab875fSJohannes Doerfert   }
35467ab875fSJohannes Doerfert 
DynamicNextChunkomptarget_nvptx_LoopSupport35567ab875fSJohannes Doerfert   static int DynamicNextChunk(T &lb, T &ub, T chunkSize, T loopLowerBound,
35667ab875fSJohannes Doerfert                               T loopUpperBound) {
35767ab875fSJohannes Doerfert     T N = NextIter();
35867ab875fSJohannes Doerfert     lb = loopLowerBound + N * chunkSize;
35967ab875fSJohannes Doerfert     ub = lb + chunkSize - 1; // Clang uses i <= ub
36067ab875fSJohannes Doerfert 
36167ab875fSJohannes Doerfert     // 3 result cases:
36267ab875fSJohannes Doerfert     //  a. lb and ub < loopUpperBound --> NOT_FINISHED
36367ab875fSJohannes Doerfert     //  b. lb < loopUpperBound and ub >= loopUpperBound: last chunk -->
36467ab875fSJohannes Doerfert     //  NOT_FINISHED
36567ab875fSJohannes Doerfert     //  c. lb and ub >= loopUpperBound: empty chunk --> FINISHED
36667ab875fSJohannes Doerfert     // a.
36767ab875fSJohannes Doerfert     if (lb <= loopUpperBound && ub < loopUpperBound) {
36867ab875fSJohannes Doerfert       return NOT_FINISHED;
36967ab875fSJohannes Doerfert     }
37067ab875fSJohannes Doerfert     // b.
37167ab875fSJohannes Doerfert     if (lb <= loopUpperBound) {
37267ab875fSJohannes Doerfert       ub = loopUpperBound;
37367ab875fSJohannes Doerfert       return LAST_CHUNK;
37467ab875fSJohannes Doerfert     }
37567ab875fSJohannes Doerfert     // c. if we are here, we are in case 'c'
37667ab875fSJohannes Doerfert     lb = loopUpperBound + 2;
37767ab875fSJohannes Doerfert     ub = loopUpperBound + 1;
37867ab875fSJohannes Doerfert     return FINISHED;
37967ab875fSJohannes Doerfert   }
38067ab875fSJohannes Doerfert 
dispatch_nextomptarget_nvptx_LoopSupport38167ab875fSJohannes Doerfert   static int dispatch_next(IdentTy *loc, int32_t gtid, int32_t *plast,
38267ab875fSJohannes Doerfert                            T *plower, T *pupper, ST *pstride,
38367ab875fSJohannes Doerfert                            DynamicScheduleTracker *DST) {
38467ab875fSJohannes Doerfert     // ID of a thread in its own warp
38567ab875fSJohannes Doerfert 
38667ab875fSJohannes Doerfert     // automatically selects thread or warp ID based on selected implementation
38767ab875fSJohannes Doerfert     ASSERT0(LT_FUSSY, gtid < omp_get_num_threads(),
38867ab875fSJohannes Doerfert             "current thread is not needed here; error");
38967ab875fSJohannes Doerfert     // retrieve schedule
39067ab875fSJohannes Doerfert     kmp_sched_t schedule = DST->ScheduleType;
39167ab875fSJohannes Doerfert 
39267ab875fSJohannes Doerfert     // xxx reduce to one
39367ab875fSJohannes Doerfert     if (schedule == kmp_sched_static_chunk ||
39467ab875fSJohannes Doerfert         schedule == kmp_sched_static_nochunk) {
39567ab875fSJohannes Doerfert       T myLb = DST->NextLowerBound;
39667ab875fSJohannes Doerfert       T ub = DST->LoopUpperBound;
39767ab875fSJohannes Doerfert       // finished?
39867ab875fSJohannes Doerfert       if (myLb > ub) {
39967ab875fSJohannes Doerfert         return DISPATCH_FINISHED;
40067ab875fSJohannes Doerfert       }
40167ab875fSJohannes Doerfert       // not finished, save current bounds
40267ab875fSJohannes Doerfert       ST chunk = DST->Chunk;
40367ab875fSJohannes Doerfert       *plower = myLb;
40467ab875fSJohannes Doerfert       T myUb = myLb + chunk - 1; // Clang uses i <= ub
40567ab875fSJohannes Doerfert       if (myUb > ub)
40667ab875fSJohannes Doerfert         myUb = ub;
40767ab875fSJohannes Doerfert       *pupper = myUb;
40867ab875fSJohannes Doerfert       *plast = (int32_t)(myUb == ub);
40967ab875fSJohannes Doerfert 
41067ab875fSJohannes Doerfert       // increment next lower bound by the stride
41167ab875fSJohannes Doerfert       ST stride = DST->Stride;
41267ab875fSJohannes Doerfert       DST->NextLowerBound = myLb + stride;
41367ab875fSJohannes Doerfert       return DISPATCH_NOTFINISHED;
41467ab875fSJohannes Doerfert     }
41567ab875fSJohannes Doerfert     ASSERT0(LT_FUSSY,
41667ab875fSJohannes Doerfert             schedule == kmp_sched_dynamic || schedule == kmp_sched_guided,
41767ab875fSJohannes Doerfert             "bad sched");
41867ab875fSJohannes Doerfert     T myLb, myUb;
41967ab875fSJohannes Doerfert     int finished = DynamicNextChunk(myLb, myUb, DST->Chunk, DST->NextLowerBound,
42067ab875fSJohannes Doerfert                                     DST->LoopUpperBound);
42167ab875fSJohannes Doerfert 
42267ab875fSJohannes Doerfert     if (finished == FINISHED)
42367ab875fSJohannes Doerfert       return DISPATCH_FINISHED;
42467ab875fSJohannes Doerfert 
42567ab875fSJohannes Doerfert     // not finished (either not finished or last chunk)
42667ab875fSJohannes Doerfert     *plast = (int32_t)(finished == LAST_CHUNK);
42767ab875fSJohannes Doerfert     *plower = myLb;
42867ab875fSJohannes Doerfert     *pupper = myUb;
42967ab875fSJohannes Doerfert     *pstride = 1;
43067ab875fSJohannes Doerfert 
43167ab875fSJohannes Doerfert     return DISPATCH_NOTFINISHED;
43267ab875fSJohannes Doerfert   }
43367ab875fSJohannes Doerfert 
dispatch_finiomptarget_nvptx_LoopSupport43467ab875fSJohannes Doerfert   static void dispatch_fini() {
43567ab875fSJohannes Doerfert     // nothing
43667ab875fSJohannes Doerfert   }
43767ab875fSJohannes Doerfert 
43867ab875fSJohannes Doerfert   ////////////////////////////////////////////////////////////////////////////////
43967ab875fSJohannes Doerfert   // end of template class that encapsulate all the helper functions
44067ab875fSJohannes Doerfert   ////////////////////////////////////////////////////////////////////////////////
44167ab875fSJohannes Doerfert };
44267ab875fSJohannes Doerfert 
44367ab875fSJohannes Doerfert ////////////////////////////////////////////////////////////////////////////////
44467ab875fSJohannes Doerfert // KMP interface implementation (dyn loops)
44567ab875fSJohannes Doerfert ////////////////////////////////////////////////////////////////////////////////
44667ab875fSJohannes Doerfert 
44767ab875fSJohannes Doerfert // TODO: This is a stopgap. We probably want to expand the dispatch API to take
44867ab875fSJohannes Doerfert //       an DST pointer which can then be allocated properly without malloc.
4494863fed9SJoseph Huber static DynamicScheduleTracker *THREAD_LOCAL(ThreadDSTPtr);
45067ab875fSJohannes Doerfert 
45167ab875fSJohannes Doerfert // Create a new DST, link the current one, and define the new as current.
pushDST()45267ab875fSJohannes Doerfert static DynamicScheduleTracker *pushDST() {
45367ab875fSJohannes Doerfert   DynamicScheduleTracker *NewDST = static_cast<DynamicScheduleTracker *>(
45467ab875fSJohannes Doerfert       memory::allocGlobal(sizeof(DynamicScheduleTracker), "new DST"));
45567ab875fSJohannes Doerfert   *NewDST = DynamicScheduleTracker({0});
45667ab875fSJohannes Doerfert   NewDST->NextDST = ThreadDSTPtr;
45767ab875fSJohannes Doerfert   ThreadDSTPtr = NewDST;
45867ab875fSJohannes Doerfert   return ThreadDSTPtr;
45967ab875fSJohannes Doerfert }
46067ab875fSJohannes Doerfert 
46167ab875fSJohannes Doerfert // Return the current DST.
peekDST()46267ab875fSJohannes Doerfert static DynamicScheduleTracker *peekDST() { return ThreadDSTPtr; }
46367ab875fSJohannes Doerfert 
46467ab875fSJohannes Doerfert // Pop the current DST and restore the last one.
popDST()46567ab875fSJohannes Doerfert static void popDST() {
46667ab875fSJohannes Doerfert   DynamicScheduleTracker *OldDST = ThreadDSTPtr->NextDST;
46767ab875fSJohannes Doerfert   memory::freeGlobal(ThreadDSTPtr, "remove DST");
46867ab875fSJohannes Doerfert   ThreadDSTPtr = OldDST;
46967ab875fSJohannes Doerfert }
47067ab875fSJohannes Doerfert 
47167ab875fSJohannes Doerfert extern "C" {
47267ab875fSJohannes Doerfert 
47367ab875fSJohannes Doerfert // init
__kmpc_dispatch_init_4(IdentTy * loc,int32_t tid,int32_t schedule,int32_t lb,int32_t ub,int32_t st,int32_t chunk)47467ab875fSJohannes Doerfert void __kmpc_dispatch_init_4(IdentTy *loc, int32_t tid, int32_t schedule,
47567ab875fSJohannes Doerfert                             int32_t lb, int32_t ub, int32_t st, int32_t chunk) {
47674f91741SJoseph Huber   FunctionTracingRAII();
47767ab875fSJohannes Doerfert   DynamicScheduleTracker *DST = pushDST();
47867ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<int32_t, int32_t>::dispatch_init(
47967ab875fSJohannes Doerfert       loc, tid, (kmp_sched_t)schedule, lb, ub, st, chunk, DST);
48067ab875fSJohannes Doerfert }
48167ab875fSJohannes Doerfert 
__kmpc_dispatch_init_4u(IdentTy * loc,int32_t tid,int32_t schedule,uint32_t lb,uint32_t ub,int32_t st,int32_t chunk)48267ab875fSJohannes Doerfert void __kmpc_dispatch_init_4u(IdentTy *loc, int32_t tid, int32_t schedule,
48367ab875fSJohannes Doerfert                              uint32_t lb, uint32_t ub, int32_t st,
48467ab875fSJohannes Doerfert                              int32_t chunk) {
48574f91741SJoseph Huber   FunctionTracingRAII();
48667ab875fSJohannes Doerfert   DynamicScheduleTracker *DST = pushDST();
48767ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<uint32_t, int32_t>::dispatch_init(
48867ab875fSJohannes Doerfert       loc, tid, (kmp_sched_t)schedule, lb, ub, st, chunk, DST);
48967ab875fSJohannes Doerfert }
49067ab875fSJohannes Doerfert 
__kmpc_dispatch_init_8(IdentTy * loc,int32_t tid,int32_t schedule,int64_t lb,int64_t ub,int64_t st,int64_t chunk)49167ab875fSJohannes Doerfert void __kmpc_dispatch_init_8(IdentTy *loc, int32_t tid, int32_t schedule,
49267ab875fSJohannes Doerfert                             int64_t lb, int64_t ub, int64_t st, int64_t chunk) {
49374f91741SJoseph Huber   FunctionTracingRAII();
49467ab875fSJohannes Doerfert   DynamicScheduleTracker *DST = pushDST();
49567ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<int64_t, int64_t>::dispatch_init(
49667ab875fSJohannes Doerfert       loc, tid, (kmp_sched_t)schedule, lb, ub, st, chunk, DST);
49767ab875fSJohannes Doerfert }
49867ab875fSJohannes Doerfert 
__kmpc_dispatch_init_8u(IdentTy * loc,int32_t tid,int32_t schedule,uint64_t lb,uint64_t ub,int64_t st,int64_t chunk)49967ab875fSJohannes Doerfert void __kmpc_dispatch_init_8u(IdentTy *loc, int32_t tid, int32_t schedule,
50067ab875fSJohannes Doerfert                              uint64_t lb, uint64_t ub, int64_t st,
50167ab875fSJohannes Doerfert                              int64_t chunk) {
50274f91741SJoseph Huber   FunctionTracingRAII();
50367ab875fSJohannes Doerfert   DynamicScheduleTracker *DST = pushDST();
50467ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<uint64_t, int64_t>::dispatch_init(
50567ab875fSJohannes Doerfert       loc, tid, (kmp_sched_t)schedule, lb, ub, st, chunk, DST);
50667ab875fSJohannes Doerfert }
50767ab875fSJohannes Doerfert 
50867ab875fSJohannes Doerfert // next
__kmpc_dispatch_next_4(IdentTy * loc,int32_t tid,int32_t * p_last,int32_t * p_lb,int32_t * p_ub,int32_t * p_st)50967ab875fSJohannes Doerfert int __kmpc_dispatch_next_4(IdentTy *loc, int32_t tid, int32_t *p_last,
51067ab875fSJohannes Doerfert                            int32_t *p_lb, int32_t *p_ub, int32_t *p_st) {
51174f91741SJoseph Huber   FunctionTracingRAII();
51267ab875fSJohannes Doerfert   DynamicScheduleTracker *DST = peekDST();
51367ab875fSJohannes Doerfert   return omptarget_nvptx_LoopSupport<int32_t, int32_t>::dispatch_next(
51467ab875fSJohannes Doerfert       loc, tid, p_last, p_lb, p_ub, p_st, DST);
51567ab875fSJohannes Doerfert }
51667ab875fSJohannes Doerfert 
__kmpc_dispatch_next_4u(IdentTy * loc,int32_t tid,int32_t * p_last,uint32_t * p_lb,uint32_t * p_ub,int32_t * p_st)51767ab875fSJohannes Doerfert int __kmpc_dispatch_next_4u(IdentTy *loc, int32_t tid, int32_t *p_last,
51867ab875fSJohannes Doerfert                             uint32_t *p_lb, uint32_t *p_ub, int32_t *p_st) {
51974f91741SJoseph Huber   FunctionTracingRAII();
52067ab875fSJohannes Doerfert   DynamicScheduleTracker *DST = peekDST();
52167ab875fSJohannes Doerfert   return omptarget_nvptx_LoopSupport<uint32_t, int32_t>::dispatch_next(
52267ab875fSJohannes Doerfert       loc, tid, p_last, p_lb, p_ub, p_st, DST);
52367ab875fSJohannes Doerfert }
52467ab875fSJohannes Doerfert 
__kmpc_dispatch_next_8(IdentTy * loc,int32_t tid,int32_t * p_last,int64_t * p_lb,int64_t * p_ub,int64_t * p_st)52567ab875fSJohannes Doerfert int __kmpc_dispatch_next_8(IdentTy *loc, int32_t tid, int32_t *p_last,
52667ab875fSJohannes Doerfert                            int64_t *p_lb, int64_t *p_ub, int64_t *p_st) {
52774f91741SJoseph Huber   FunctionTracingRAII();
52867ab875fSJohannes Doerfert   DynamicScheduleTracker *DST = peekDST();
52967ab875fSJohannes Doerfert   return omptarget_nvptx_LoopSupport<int64_t, int64_t>::dispatch_next(
53067ab875fSJohannes Doerfert       loc, tid, p_last, p_lb, p_ub, p_st, DST);
53167ab875fSJohannes Doerfert }
53267ab875fSJohannes Doerfert 
__kmpc_dispatch_next_8u(IdentTy * loc,int32_t tid,int32_t * p_last,uint64_t * p_lb,uint64_t * p_ub,int64_t * p_st)53367ab875fSJohannes Doerfert int __kmpc_dispatch_next_8u(IdentTy *loc, int32_t tid, int32_t *p_last,
53467ab875fSJohannes Doerfert                             uint64_t *p_lb, uint64_t *p_ub, int64_t *p_st) {
53574f91741SJoseph Huber   FunctionTracingRAII();
53667ab875fSJohannes Doerfert   DynamicScheduleTracker *DST = peekDST();
53767ab875fSJohannes Doerfert   return omptarget_nvptx_LoopSupport<uint64_t, int64_t>::dispatch_next(
53867ab875fSJohannes Doerfert       loc, tid, p_last, p_lb, p_ub, p_st, DST);
53967ab875fSJohannes Doerfert }
54067ab875fSJohannes Doerfert 
54167ab875fSJohannes Doerfert // fini
__kmpc_dispatch_fini_4(IdentTy * loc,int32_t tid)54267ab875fSJohannes Doerfert void __kmpc_dispatch_fini_4(IdentTy *loc, int32_t tid) {
54374f91741SJoseph Huber   FunctionTracingRAII();
54467ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<int32_t, int32_t>::dispatch_fini();
54567ab875fSJohannes Doerfert   popDST();
54667ab875fSJohannes Doerfert }
54767ab875fSJohannes Doerfert 
__kmpc_dispatch_fini_4u(IdentTy * loc,int32_t tid)54867ab875fSJohannes Doerfert void __kmpc_dispatch_fini_4u(IdentTy *loc, int32_t tid) {
54974f91741SJoseph Huber   FunctionTracingRAII();
55067ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<uint32_t, int32_t>::dispatch_fini();
55167ab875fSJohannes Doerfert   popDST();
55267ab875fSJohannes Doerfert }
55367ab875fSJohannes Doerfert 
__kmpc_dispatch_fini_8(IdentTy * loc,int32_t tid)55467ab875fSJohannes Doerfert void __kmpc_dispatch_fini_8(IdentTy *loc, int32_t tid) {
55574f91741SJoseph Huber   FunctionTracingRAII();
55667ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<int64_t, int64_t>::dispatch_fini();
55767ab875fSJohannes Doerfert   popDST();
55867ab875fSJohannes Doerfert }
55967ab875fSJohannes Doerfert 
__kmpc_dispatch_fini_8u(IdentTy * loc,int32_t tid)56067ab875fSJohannes Doerfert void __kmpc_dispatch_fini_8u(IdentTy *loc, int32_t tid) {
56174f91741SJoseph Huber   FunctionTracingRAII();
56267ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<uint64_t, int64_t>::dispatch_fini();
56367ab875fSJohannes Doerfert   popDST();
56467ab875fSJohannes Doerfert }
56567ab875fSJohannes Doerfert 
56667ab875fSJohannes Doerfert ////////////////////////////////////////////////////////////////////////////////
56767ab875fSJohannes Doerfert // KMP interface implementation (static loops)
56867ab875fSJohannes Doerfert ////////////////////////////////////////////////////////////////////////////////
56967ab875fSJohannes Doerfert 
__kmpc_for_static_init_4(IdentTy * loc,int32_t global_tid,int32_t schedtype,int32_t * plastiter,int32_t * plower,int32_t * pupper,int32_t * pstride,int32_t incr,int32_t chunk)57067ab875fSJohannes Doerfert void __kmpc_for_static_init_4(IdentTy *loc, int32_t global_tid,
57167ab875fSJohannes Doerfert                               int32_t schedtype, int32_t *plastiter,
57267ab875fSJohannes Doerfert                               int32_t *plower, int32_t *pupper,
57367ab875fSJohannes Doerfert                               int32_t *pstride, int32_t incr, int32_t chunk) {
57474f91741SJoseph Huber   FunctionTracingRAII();
57567ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<int32_t, int32_t>::for_static_init(
57667ab875fSJohannes Doerfert       global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
57767ab875fSJohannes Doerfert       mapping::isSPMDMode());
57867ab875fSJohannes Doerfert }
57967ab875fSJohannes Doerfert 
__kmpc_for_static_init_4u(IdentTy * loc,int32_t global_tid,int32_t schedtype,int32_t * plastiter,uint32_t * plower,uint32_t * pupper,int32_t * pstride,int32_t incr,int32_t chunk)58067ab875fSJohannes Doerfert void __kmpc_for_static_init_4u(IdentTy *loc, int32_t global_tid,
58167ab875fSJohannes Doerfert                                int32_t schedtype, int32_t *plastiter,
58267ab875fSJohannes Doerfert                                uint32_t *plower, uint32_t *pupper,
58367ab875fSJohannes Doerfert                                int32_t *pstride, int32_t incr, int32_t chunk) {
58474f91741SJoseph Huber   FunctionTracingRAII();
58567ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<uint32_t, int32_t>::for_static_init(
58667ab875fSJohannes Doerfert       global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
58767ab875fSJohannes Doerfert       mapping::isSPMDMode());
58867ab875fSJohannes Doerfert }
58967ab875fSJohannes Doerfert 
__kmpc_for_static_init_8(IdentTy * loc,int32_t global_tid,int32_t schedtype,int32_t * plastiter,int64_t * plower,int64_t * pupper,int64_t * pstride,int64_t incr,int64_t chunk)59067ab875fSJohannes Doerfert void __kmpc_for_static_init_8(IdentTy *loc, int32_t global_tid,
59167ab875fSJohannes Doerfert                               int32_t schedtype, int32_t *plastiter,
59267ab875fSJohannes Doerfert                               int64_t *plower, int64_t *pupper,
59367ab875fSJohannes Doerfert                               int64_t *pstride, int64_t incr, int64_t chunk) {
59474f91741SJoseph Huber   FunctionTracingRAII();
59567ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<int64_t, int64_t>::for_static_init(
59667ab875fSJohannes Doerfert       global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
59767ab875fSJohannes Doerfert       mapping::isSPMDMode());
59867ab875fSJohannes Doerfert }
59967ab875fSJohannes Doerfert 
__kmpc_for_static_init_8u(IdentTy * loc,int32_t global_tid,int32_t schedtype,int32_t * plastiter,uint64_t * plower,uint64_t * pupper,int64_t * pstride,int64_t incr,int64_t chunk)60067ab875fSJohannes Doerfert void __kmpc_for_static_init_8u(IdentTy *loc, int32_t global_tid,
60167ab875fSJohannes Doerfert                                int32_t schedtype, int32_t *plastiter,
60267ab875fSJohannes Doerfert                                uint64_t *plower, uint64_t *pupper,
60367ab875fSJohannes Doerfert                                int64_t *pstride, int64_t incr, int64_t chunk) {
60474f91741SJoseph Huber   FunctionTracingRAII();
60567ab875fSJohannes Doerfert   omptarget_nvptx_LoopSupport<uint64_t, int64_t>::for_static_init(
60667ab875fSJohannes Doerfert       global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
60767ab875fSJohannes Doerfert       mapping::isSPMDMode());
60867ab875fSJohannes Doerfert }
60967ab875fSJohannes Doerfert 
__kmpc_distribute_static_init_4(IdentTy * loc,int32_t global_tid,int32_t schedtype,int32_t * plastiter,int32_t * plower,int32_t * pupper,int32_t * pstride,int32_t incr,int32_t chunk)61074d622deSJoseph Huber void __kmpc_distribute_static_init_4(IdentTy *loc, int32_t global_tid,
61174d622deSJoseph Huber                                      int32_t schedtype, int32_t *plastiter,
61274d622deSJoseph Huber                                      int32_t *plower, int32_t *pupper,
61374d622deSJoseph Huber                                      int32_t *pstride, int32_t incr,
61474d622deSJoseph Huber                                      int32_t chunk) {
61574f91741SJoseph Huber   FunctionTracingRAII();
61674d622deSJoseph Huber   omptarget_nvptx_LoopSupport<int32_t, int32_t>::for_static_init(
61774d622deSJoseph Huber       global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
61874d622deSJoseph Huber       mapping::isSPMDMode());
61974d622deSJoseph Huber }
62074d622deSJoseph Huber 
__kmpc_distribute_static_init_4u(IdentTy * loc,int32_t global_tid,int32_t schedtype,int32_t * plastiter,uint32_t * plower,uint32_t * pupper,int32_t * pstride,int32_t incr,int32_t chunk)62174d622deSJoseph Huber void __kmpc_distribute_static_init_4u(IdentTy *loc, int32_t global_tid,
62274d622deSJoseph Huber                                       int32_t schedtype, int32_t *plastiter,
62374d622deSJoseph Huber                                       uint32_t *plower, uint32_t *pupper,
62474d622deSJoseph Huber                                       int32_t *pstride, int32_t incr,
62574d622deSJoseph Huber                                       int32_t chunk) {
62674f91741SJoseph Huber   FunctionTracingRAII();
62774d622deSJoseph Huber   omptarget_nvptx_LoopSupport<uint32_t, int32_t>::for_static_init(
62874d622deSJoseph Huber       global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
62974d622deSJoseph Huber       mapping::isSPMDMode());
63074d622deSJoseph Huber }
63174d622deSJoseph Huber 
__kmpc_distribute_static_init_8(IdentTy * loc,int32_t global_tid,int32_t schedtype,int32_t * plastiter,int64_t * plower,int64_t * pupper,int64_t * pstride,int64_t incr,int64_t chunk)63274d622deSJoseph Huber void __kmpc_distribute_static_init_8(IdentTy *loc, int32_t global_tid,
63374d622deSJoseph Huber                                      int32_t schedtype, int32_t *plastiter,
63474d622deSJoseph Huber                                      int64_t *plower, int64_t *pupper,
63574d622deSJoseph Huber                                      int64_t *pstride, int64_t incr,
63674d622deSJoseph Huber                                      int64_t chunk) {
63774f91741SJoseph Huber   FunctionTracingRAII();
63874d622deSJoseph Huber   omptarget_nvptx_LoopSupport<int64_t, int64_t>::for_static_init(
63974d622deSJoseph Huber       global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
64074d622deSJoseph Huber       mapping::isSPMDMode());
64174d622deSJoseph Huber }
64274d622deSJoseph Huber 
__kmpc_distribute_static_init_8u(IdentTy * loc,int32_t global_tid,int32_t schedtype,int32_t * plastiter,uint64_t * plower,uint64_t * pupper,int64_t * pstride,int64_t incr,int64_t chunk)64374d622deSJoseph Huber void __kmpc_distribute_static_init_8u(IdentTy *loc, int32_t global_tid,
64474d622deSJoseph Huber                                       int32_t schedtype, int32_t *plastiter,
64574d622deSJoseph Huber                                       uint64_t *plower, uint64_t *pupper,
64674d622deSJoseph Huber                                       int64_t *pstride, int64_t incr,
64774d622deSJoseph Huber                                       int64_t chunk) {
64874f91741SJoseph Huber   FunctionTracingRAII();
64974d622deSJoseph Huber   omptarget_nvptx_LoopSupport<uint64_t, int64_t>::for_static_init(
65074d622deSJoseph Huber       global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
65174d622deSJoseph Huber       mapping::isSPMDMode());
65274d622deSJoseph Huber }
65374d622deSJoseph Huber 
__kmpc_for_static_fini(IdentTy * loc,int32_t global_tid)65474f91741SJoseph Huber void __kmpc_for_static_fini(IdentTy *loc, int32_t global_tid) {
65574f91741SJoseph Huber   FunctionTracingRAII();
65674f91741SJoseph Huber }
65774d622deSJoseph Huber 
__kmpc_distribute_static_fini(IdentTy * loc,int32_t global_tid)65874f91741SJoseph Huber void __kmpc_distribute_static_fini(IdentTy *loc, int32_t global_tid) {
65974f91741SJoseph Huber   FunctionTracingRAII();
66074f91741SJoseph Huber }
66167ab875fSJohannes Doerfert }
66267ab875fSJohannes Doerfert 
66367ab875fSJohannes Doerfert #pragma omp end declare target
664