[llvm-branch-commits] [llvm] [offload][omp] Move OpenMP KLE to libomptarget (PR #223761)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 15 10:06:52 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-offload
Author: Alex Duran (adurang)
<details>
<summary>Changes</summary>
Move preparations related to OpenMP KLE and dynamicCGroupMem fallback out of the plugins into libomptarget.
Resructure Device::launch as it grew too large.
Assisted by Claude.
---
Patch is 34.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/223761.diff
6 Files Affected:
- (modified) offload/include/device.h (+1)
- (modified) offload/libompaccsupport/PluginManager.cpp (+1)
- (modified) offload/libompaccsupport/device.cpp (+291-61)
- (modified) offload/plugins-nextgen/common/include/PluginInterface.h (+5-50)
- (modified) offload/plugins-nextgen/common/src/PluginInterface.cpp (+2-144)
- (modified) offload/plugins-nextgen/common/src/RecordReplay.cpp (+1-1)
``````````diff
diff --git a/offload/include/device.h b/offload/include/device.h
index 9c5fa061ec608..c4bcec5a71805 100644
--- a/offload/include/device.h
+++ b/offload/include/device.h
@@ -49,6 +49,7 @@ struct KernelLaunchInfoTy {
uint32_t MaxNumThreads = 0;
uint32_t PreferredNumThreads = 0;
uint32_t ReductionDataSize = 0;
+ uint32_t StaticBlockMemSize = 0;
llvm::omp::OMPTgtExecModeFlags Mode = llvm::omp::OMP_TGT_EXEC_MODE_BARE;
bool isBareMode() const { return Mode == llvm::omp::OMP_TGT_EXEC_MODE_BARE; }
diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp
index babd9347655d2..9c9f2edb3fca9 100644
--- a/offload/libompaccsupport/PluginManager.cpp
+++ b/offload/libompaccsupport/PluginManager.cpp
@@ -529,6 +529,7 @@ static int loadImagesOntoDevice(DeviceTy &Device) {
? std::max(Cfg.MinThreads,
int32_t(GenericDevice.getDefaultNumThreads()))
: GenericDevice.getDefaultNumThreads();
+ LaunchInfo.StaticBlockMemSize = Kernel->getStaticBlockMemSize();
Device.setKernelLaunchInfo(DeviceEntry.Address, LaunchInfo);
}
diff --git a/offload/libompaccsupport/device.cpp b/offload/libompaccsupport/device.cpp
index 14ab45709d0d5..a198a4a900835 100644
--- a/offload/libompaccsupport/device.cpp
+++ b/offload/libompaccsupport/device.cpp
@@ -389,6 +389,152 @@ static void resolveKernelLaunchParams(void **const TgtArgs,
LaunchArgs.Args = &Ptrs[0];
}
+namespace {
+/// Configuration of dynamic block memory needed for launching a kernel.
+struct DynBlockMemConfTy {
+ /// The size of the dynamic block memory buffer.
+ uint32_t Size = 0;
+ /// The size of dynamic shared memory natively provided by the device.
+ uint32_t NativeSize = 0;
+ /// The fallback that was triggered (if any).
+ DynCGroupMemFallbackType Fallback = DynCGroupMemFallbackType::None;
+ /// The fallback pointer if global memory was used as alternative.
+ void *FallbackPtr = nullptr;
+};
+} // namespace
+
+/// Prepare the block memory buffer requested for the kernel and execute the
+/// specified fallback if necessary.
+static llvm::Expected<DynBlockMemConfTy>
+prepareBlockMemory(GenericDeviceTy &GenericDevice,
+ const KernelLaunchInfoTy &KernelEnv, uint32_t DynCGroupMem,
+ DynCGroupMemFallbackType DynCGroupMemFallback,
+ uint32_t NumBlocks) {
+ uint32_t MaxBlockMemSize = GenericDevice.getMaxBlockSharedMemSize();
+ uint32_t DynBlockMemSize = DynCGroupMem;
+ uint32_t TotalBlockMemSize = KernelEnv.StaticBlockMemSize + DynBlockMemSize;
+ uint32_t DynNativeBlockMemSize = DynBlockMemSize;
+ void *DynFallbackPtr = nullptr;
+
+ // No enough block memory to cover the static one. Cannot run the kernel.
+ if (KernelEnv.StaticBlockMemSize > MaxBlockMemSize)
+ return error::createOffloadError(
+ error::ErrorCode::INVALID_ARGUMENT,
+ "Static block memory size exceeds maximum");
+ // No enough block memory to cover dynamic one, and the fallback is aborting.
+ if (DynCGroupMemFallback == DynCGroupMemFallbackType::Abort &&
+ TotalBlockMemSize > MaxBlockMemSize)
+ return error::createOffloadError(
+ error::ErrorCode::INVALID_ARGUMENT,
+ "Requested block memory size (static + dynamic) exceeds maximum");
+
+ DynCGroupMemFallbackType DynFallback = DynCGroupMemFallbackType::None;
+ if (DynBlockMemSize && TotalBlockMemSize > MaxBlockMemSize) {
+ // Launch without native dynamic block memory.
+ DynNativeBlockMemSize = 0;
+ DynFallback = DynCGroupMemFallback;
+ if (DynFallback != DynCGroupMemFallbackType::DefaultMem) {
+ // Do not provide any memory as fallback.
+ DynBlockMemSize = 0;
+ } else {
+ // Get global memory as fallback.
+ auto AllocOrErr = GenericDevice.dataAlloc(
+ NumBlocks * DynBlockMemSize,
+ /*HostPtr=*/nullptr, TARGET_ALLOC_DEVICE, /*Alignment=*/0);
+ if (!AllocOrErr)
+ return AllocOrErr.takeError();
+ DynFallbackPtr = *AllocOrErr;
+ }
+ }
+ return DynBlockMemConfTy{DynBlockMemSize, DynNativeBlockMemSize, DynFallback,
+ DynFallbackPtr};
+}
+
+static void freeAfterSynchronization(GenericDeviceTy &GenericDevice,
+ AsyncInfoTy &AsyncInfo, void *Ptr,
+ TargetAllocTy Kind) {
+ AsyncInfo.addPostProcessingFunction([&GenericDevice, Ptr, Kind]() -> int {
+ if (auto Err = GenericDevice.dataDelete(Ptr, Kind)) {
+ REPORT() << "Failure to free device memory " << Ptr << ": "
+ << toString(std::move(Err));
+ return OFFLOAD_FAIL;
+ }
+ return OFFLOAD_SUCCESS;
+ });
+}
+
+/// Return a device pointer to a new kernel launch environment, or null if
+/// this launch has no reserved dyn_ptr slot to store one in. \p NumBlocks0 is
+/// the number of blocks for this launch and is used to size the reduction
+/// buffer.
+static llvm::Expected<KernelLaunchEnvironmentTy *> getKernelLaunchEnvironment(
+ GenericDeviceTy &GenericDevice, const KernelLaunchArgsTy &LaunchArgs,
+ const KernelLaunchInfoTy &KernelEnv,
+ const DynBlockMemConfTy &DynBlockMemConf, uint32_t DynCGroupMem,
+ void **DynPtrSlot, AsyncInfoTy &AsyncInfo, uint32_t NumBlocks0) {
+ // Ctor/Dtor have no arguments, replaying uses the original kernel launch
+ // environment, and launches with no reserved dyn_ptr slot (e.g. older
+ // compiler versions, or non-OpenMP launches) have nowhere to store one.
+ if ((GenericDevice.getRecordReplay() &&
+ GenericDevice.getRecordReplay()->isReplaying()) ||
+ !DynPtrSlot)
+ return nullptr;
+
+ const bool NeedsReductionBuffer = KernelEnv.ReductionDataSize != 0;
+ if (NeedsReductionBuffer && LaunchArgs.OmpABIVersion < OMP_KERNEL_ARG_VERSION)
+ return error::createOffloadError(
+ error::ErrorCode::INVALID_BINARY,
+ "kernel was built against an older OpenMP kernel-launch-environment "
+ "ABI (v%u); current runtime requires v%u for cross-team reductions",
+ LaunchArgs.OmpABIVersion, OMP_KERNEL_ARG_VERSION);
+ if (!NeedsReductionBuffer && !DynCGroupMem)
+ return reinterpret_cast<KernelLaunchEnvironmentTy *>(~0);
+
+ auto AllocOrErr = GenericDevice.dataAlloc(
+ sizeof(KernelLaunchEnvironmentTy),
+ /*HostPtr=*/nullptr, TARGET_ALLOC_DEVICE, /*Alignment=*/0);
+ if (!AllocOrErr)
+ return AllocOrErr.takeError();
+
+ // Remember to free the memory later.
+ freeAfterSynchronization(GenericDevice, AsyncInfo, *AllocOrErr,
+ TARGET_ALLOC_DEVICE);
+
+ // Use the KLE in the __tgt_async_info to ensure a stable address for the
+ // async data transfer.
+ auto &LocalKLE =
+ static_cast<__tgt_async_info *>(AsyncInfo)->KernelLaunchEnvironment;
+ LocalKLE = KernelLaunchEnvironmentTy{};
+ LocalKLE.DynCGroupMemSize = DynBlockMemConf.Size;
+ LocalKLE.DynCGroupMemFbPtr = DynBlockMemConf.FallbackPtr;
+ LocalKLE.DynCGroupMemFb = DynBlockMemConf.Fallback;
+ LocalKLE.ReductionBuffer = nullptr;
+
+ if (NeedsReductionBuffer) {
+ // Use number of teams many buffer elements.
+ auto ReductionAllocOrErr = GenericDevice.dataAlloc(
+ uint64_t(KernelEnv.ReductionDataSize) * NumBlocks0,
+ /*HostPtr=*/nullptr, TARGET_ALLOC_DEVICE, /*Alignment=*/0);
+ if (!ReductionAllocOrErr)
+ return ReductionAllocOrErr.takeError();
+ LocalKLE.ReductionBuffer = *ReductionAllocOrErr;
+ // Remember to free the memory later.
+ freeAfterSynchronization(GenericDevice, AsyncInfo, *ReductionAllocOrErr,
+ TARGET_ALLOC_DEVICE);
+ }
+
+ INFO(OMP_INFOTYPE_DATA_TRANSFER, GenericDevice.getDeviceId(),
+ "Copying data from host to device, HstPtr=" DPxMOD ", TgtPtr=" DPxMOD
+ ", Size=%" PRId64 ", Name=KernelLaunchEnv\n",
+ DPxPTR(&LocalKLE), DPxPTR(*AllocOrErr),
+ sizeof(KernelLaunchEnvironmentTy));
+
+ if (auto Err = GenericDevice.dataSubmit(
+ *AllocOrErr, &LocalKLE, sizeof(KernelLaunchEnvironmentTy), AsyncInfo))
+ return Err;
+ return static_cast<KernelLaunchEnvironmentTy *>(*AllocOrErr);
+}
+
/// Get the effective number of threads for the kernel based on the
/// user-defined number of threads.
static uint32_t getEffectiveNumThreads(GenericDeviceTy &GenericDevice,
@@ -505,32 +651,27 @@ getEffectiveNumBlocks(GenericDeviceTy &GenericDevice, uint32_t UserNumBlocks,
GenericDevice.getBlockLimit(EffectiveNumThreads));
}
-// Run region on device
-int32_t DeviceTy::launchKernel(void *TgtEntryPtr, void **TgtVarsPtr,
- ptrdiff_t *TgtOffsets, KernelArgsTy &KernelArgs,
- KernelReplayOutcomeTy *ReplayOutcome,
- AsyncInfoTy &AsyncInfo) {
- llvm::SmallVector<void *> Args, Ptrs;
- llvm::SmallVector<int64_t> ArgSizes;
-
+/// Build the base KernelLaunchArgsTy for a launch from the public
+/// KernelArgsTy and the kernel's cached launch-geometry properties.
+static KernelLaunchArgsTy buildLaunchArgs(const KernelArgsTy &KernelArgs,
+ KernelReplayOutcomeTy *ReplayOutcome,
+ const KernelLaunchInfoTy &KernelEnv) {
KernelLaunchArgsTy LaunchArgs;
LaunchArgs.OmpABIVersion = KernelArgs.Version;
LaunchArgs.ReplayOutcome = ReplayOutcome;
LaunchArgs.ArgSizes = KernelArgs.ArgSizes;
LaunchArgs.Tripcount = KernelArgs.Tripcount;
- LaunchArgs.DynCGroupMem = KernelArgs.DynCGroupMem;
llvm::copy(KernelArgs.UserNumBlocks, LaunchArgs.UserNumBlocks);
llvm::copy(KernelArgs.UserThreadLimit, LaunchArgs.UserThreadLimit);
LaunchArgs.Flags.Cooperative = KernelArgs.Flags.Cooperative;
- LaunchArgs.Flags.DynCGroupMemFallback = KernelArgs.Flags.DynCGroupMemFallback;
-
- KernelLaunchInfoTy KernelEnv = getKernelLaunchInfo(TgtEntryPtr);
- LaunchArgs.KernelEnvironment.ReductionDataSize = KernelEnv.ReductionDataSize;
- LaunchArgs.KernelEnvironment.MaxNumThreads = KernelEnv.MaxNumThreads;
-
- const bool StrictBlocks = KernelArgs.Flags.StrictBlocks;
- const bool StrictThreads = KernelArgs.Flags.StrictThreads;
+ LaunchArgs.MaxNumThreads = KernelEnv.MaxNumThreads;
+ return LaunchArgs;
+}
+/// Assert the launch geometry invariants expected by the plugin layer.
+static void checkLaunchInvariants(const KernelLaunchArgsTy &LaunchArgs,
+ const KernelArgsTy &KernelArgs,
+ const KernelLaunchInfoTy &KernelEnv) {
// Multidimensional is only supported with bare mode for now.
assert(KernelEnv.isBareMode() ||
LaunchArgs.UserThreadLimit[1] == 1 &&
@@ -540,41 +681,58 @@ int32_t DeviceTy::launchKernel(void *TgtEntryPtr, void **TgtVarsPtr,
"Non-bare mode should only use the first thread and block "
"dimensions");
- assert(!StrictBlocks ||
+ assert(!KernelArgs.Flags.StrictBlocks ||
LaunchArgs.UserNumBlocks[0] > 0 && LaunchArgs.UserNumBlocks[1] > 0 &&
LaunchArgs.UserNumBlocks[2] > 0 &&
"Strict requires number of blocks greater than zero");
- assert(!StrictThreads ||
+ assert(!KernelArgs.Flags.StrictThreads ||
LaunchArgs.UserThreadLimit[0] > 0 &&
LaunchArgs.UserThreadLimit[1] > 0 &&
LaunchArgs.UserThreadLimit[2] > 0 &&
"Strict requires number of threads greater than zero");
+}
+
+/// Calculate or adjust, in place, the effective number of threads and blocks
+/// for the first dimension, unless the caller requested strict counts.
+static void adjustEffectiveGeometry(GenericDeviceTy &GenericDevice,
+ KernelLaunchArgsTy &LaunchArgs,
+ const KernelArgsTy &KernelArgs,
+ const KernelLaunchInfoTy &KernelEnv) {
+ const bool StrictBlocks = KernelArgs.Flags.StrictBlocks;
+ const bool StrictThreads = KernelArgs.Flags.StrictThreads;
+ if (StrictThreads && StrictBlocks)
+ return;
+
+ assert(!KernelEnv.isBareMode() &&
+ "bare kernel launches must request strict thread/block counts");
// Record whether the user actually requested a thread limit (thread_limit
// clause) before possibly overwriting UserThreadLimit[0] below with the
// computed effective value.
const bool ThreadLimitFromUser = LaunchArgs.UserThreadLimit[0] > 0;
- // Calculate or adjust the effective number of threads and blocks for the
- // first dimension, if the caller didn't request strict counts.
- if (!StrictThreads || !StrictBlocks) {
- assert(!KernelEnv.isBareMode() &&
- "bare kernel launches must request strict thread/block counts");
-
- GenericDeviceTy &GenericDevice = RTL->getDevice(RTLDeviceID);
- uint32_t EffectiveNumThreads = LaunchArgs.UserThreadLimit[0];
- if (!StrictThreads)
- EffectiveNumThreads =
- getEffectiveNumThreads(GenericDevice, EffectiveNumThreads, KernelEnv);
+ uint32_t EffectiveNumThreads = LaunchArgs.UserThreadLimit[0];
+ if (!StrictThreads)
+ EffectiveNumThreads =
+ getEffectiveNumThreads(GenericDevice, EffectiveNumThreads, KernelEnv);
- if (!StrictBlocks)
- LaunchArgs.UserNumBlocks[0] = getEffectiveNumBlocks(
- GenericDevice, LaunchArgs.UserNumBlocks[0], LaunchArgs.Tripcount,
- EffectiveNumThreads, StrictThreads, ThreadLimitFromUser, KernelEnv);
+ if (!StrictBlocks)
+ LaunchArgs.UserNumBlocks[0] = getEffectiveNumBlocks(
+ GenericDevice, LaunchArgs.UserNumBlocks[0], LaunchArgs.Tripcount,
+ EffectiveNumThreads, StrictThreads, ThreadLimitFromUser, KernelEnv);
- LaunchArgs.UserThreadLimit[0] = EffectiveNumThreads;
- }
+ LaunchArgs.UserThreadLimit[0] = EffectiveNumThreads;
+}
+/// Flatten the kernel arguments into \p LaunchArgs.Args. Returns the address
+/// of the element reserved for the kernel launch environment (dyn_ptr), or
+/// null if this launch has no such slot.
+static void **resolveArgsAndDynPtrSlot(KernelArgsTy &KernelArgs,
+ void **TgtVarsPtr, ptrdiff_t *TgtOffsets,
+ llvm::SmallVector<void *> &Args,
+ llvm::SmallVector<void *> &Ptrs,
+ llvm::SmallVector<int64_t> &ArgSizes,
+ KernelLaunchArgsTy &LaunchArgs) {
if (KernelArgs.Flags.IsCUDA) {
// Kernel languages (CUDA/HIP) pass an already-flattened argument-pointer
// array through KernelArgs.ArgPtrs instead of using the OpenMP
@@ -583,34 +741,106 @@ int32_t DeviceTy::launchKernel(void *TgtEntryPtr, void **TgtVarsPtr,
reinterpret_cast<KernelLaunchParamsTy *>(KernelArgs.ArgPtrs);
LaunchArgs.NumArgs = LaunchParams->NumArgs;
LaunchArgs.Args = LaunchParams->Args;
- } else {
- resolveKernelLaunchParams(TgtVarsPtr, TgtOffsets, KernelArgs.NumArgs, Args,
- Ptrs, LaunchArgs);
- // The dyn_ptr slot is reserved by the host (version >= 4) or by
- // upgradeKernelArgs (version 3) as the last element of the argument
- // array. Version 3 device kernels expect it first instead, so rotate it
- // to the front to match that ABI.
- if (KernelArgs.NumArgs > 0 &&
- KernelArgs.Version >= OMP_KERNEL_ARG_MIN_VERSION_WITH_DYN_PTR) {
- if (KernelArgs.Version == OMP_KERNEL_ARG_MIN_VERSION_WITH_DYN_PTR) {
- std::rotate(Args.begin(), Args.end() - 1, Args.end());
- LaunchArgs.DynPtrSlot = &Args[0];
-
- // Keep ArgSizes in sync with the rotated Args, if present.
- if (LaunchArgs.ArgSizes) {
- ArgSizes.assign(LaunchArgs.ArgSizes,
- LaunchArgs.ArgSizes + KernelArgs.NumArgs);
- std::rotate(ArgSizes.begin(), ArgSizes.end() - 1, ArgSizes.end());
- LaunchArgs.ArgSizes = ArgSizes.data();
- }
- } else {
- LaunchArgs.DynPtrSlot = &Args[KernelArgs.NumArgs - 1];
- }
- }
+ return nullptr;
+ }
+
+ resolveKernelLaunchParams(TgtVarsPtr, TgtOffsets, KernelArgs.NumArgs, Args,
+ Ptrs, LaunchArgs);
+
+ if (KernelArgs.NumArgs == 0 ||
+ KernelArgs.Version < OMP_KERNEL_ARG_MIN_VERSION_WITH_DYN_PTR)
+ return nullptr;
+
+ // The dyn_ptr slot is reserved by the host (version >= 4) or by
+ // upgradeKernelArgs (version 3) as the last element of the argument array.
+ // Version 3 device kernels expect it first instead, so rotate it to the
+ // front to match that ABI.
+ if (KernelArgs.Version != OMP_KERNEL_ARG_MIN_VERSION_WITH_DYN_PTR)
+ return &Args[KernelArgs.NumArgs - 1];
+
+ std::rotate(Args.begin(), Args.end() - 1, Args.end());
+
+ // Keep ArgSizes in sync with the rotated Args, if present.
+ if (LaunchArgs.ArgSizes) {
+ ArgSizes.assign(LaunchArgs.ArgSizes,
+ LaunchArgs.ArgSizes + KernelArgs.NumArgs);
+ std::rotate(ArgSizes.begin(), ArgSizes.end() - 1, ArgSizes.end());
+ LaunchArgs.ArgSizes = ArgSizes.data();
+ }
+ return &Args[0];
+}
+
+/// Compute the dynamic block-memory configuration for this launch, filling in
+/// \p LaunchArgs.DynCGroupMem with the native size to request, and, if this
+/// launch has a reserved dyn_ptr slot (\p DynPtrSlot), the device-side kernel
+/// launch environment.
+static llvm::Error
+prepareDynamicLaunchState(GenericDeviceTy &GenericDevice,
+ const KernelLaunchInfoTy &KernelEnv,
+ KernelLaunchArgsTy &LaunchArgs, uint32_t DynCGroupMem,
+ DynCGroupMemFallbackType DynCGroupMemFallback,
+ void **DynPtrSlot, AsyncInfoTy &AsyncInfo) {
+ uint32_t NumBlocksTotal = LaunchArgs.UserNumBlocks[0] *
+ LaunchArgs.UserNumBlocks[1] *
+ LaunchArgs.UserNumBlocks[2];
+ auto DynBlockMemConfOrErr =
+ prepareBlockMemory(GenericDevice, KernelEnv, DynCGroupMem,
+ DynCGroupMemFallback, NumBlocksTotal);
+ if (!DynBlockMemConfOrErr)
+ return DynBlockMemConfOrErr.takeError();
+
+ DynBlockMemConfTy &DynBlockMemConf = *DynBlockMemConfOrErr;
+ LaunchArgs.DynCGroupMem = DynBlockMemConf.NativeSize;
+ if (DynBlockMemConf.FallbackPtr)
+ freeAfterSynchronization(GenericDevice, AsyncInfo,
+ DynBlockMemConf.FallbackPtr, TARGET_ALLOC_DEVICE);
+
+ auto KernelLaunchEnvOrErr = getKernelLaunchEnvironment(
+ GenericDevice, LaunchArgs, KernelEnv, DynBlockMemConf, DynCGroupMem,
+ DynPtrSlot, AsyncInfo, LaunchArgs.UserNumBlocks[0]);
+ if (!KernelLaunchEnvOrErr)
+ return KernelLaunchEnvOrErr.takeError();
+
+ // Fill in the kernel launch environment (dyn_ptr) if this launch has a
+ // reserved slot for it. When replaying, getKernelLaunchEnvironment()
+ // returns null so the recorded value already in the slot is preserved.
+ if (DynPtrSlot && *KernelLaunchEnvOrErr)
+ *DynPtrSlot = *KernelLaunchEnvOrErr;
+
+ return llvm::Error::success();
+}
+
+// Run region on device
+int32_t DeviceTy::launchKernel(void *TgtEntryPtr, void **TgtVarsPtr,
+ ptrdiff_t *TgtOffsets, KernelArgsTy &KernelArgs,
+ KernelReplayOutcomeTy *ReplayOutcome,
+ AsyncInfoTy &AsyncInfo) {
+ llvm::SmallVector<void *> Args, Ptrs;
+ llvm::SmallVector<int64_t> ArgSizes;
+
+ GenericDeviceTy &GenericDevice = RTL->getDevice(RTLDeviceID);
+ KernelLaunchInfoTy KernelEnv = getKernelLaunchInfo(TgtEntryPtr);
+ KernelLaunchArgsTy LaunchArgs =
+ buildLaunchArgs(KernelArgs, ReplayOutcome, KernelEnv);
+
+ checkLaunchInvariants(LaunchArgs, KernelArgs, KernelEnv);
+ adjustEffectiveGeometry(GenericDevice, LaunchArgs, KernelArgs, KernelEnv);
+
+ void **DynPtrSlot = resolveArgsAndDynPtrSlot(
+ KernelArgs, TgtVarsPtr, TgtOffsets, Args, Ptrs, ArgSizes, LaunchArgs);
+
+ auto DynCGroupMemFallback = static_cast<DynCGroupMemFallbackType>(
+ KernelArgs.Flags.DynCGroupMemFallback);
+ if (auto Err = prepareDynamicLaunchState(
+ GenericDevice, KernelEnv, LaunchArgs, KernelArgs.DynCGroupMem,
+ DynCGroupMemFallback, DynPtrSlot, AsyncInfo)) {
+ REPORT() << "Failure to prepare launch state for kernel " << TgtEntryPtr
+ << ": " << toString(std::move(Err));
+ return OFFLOAD_FAIL;
}
auto *Kernel = reinterpret_cast<GenericKern...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/223761
More information about the llvm-branch-commits
mailing list