Files
TheRock/rocm-libraries/shared/rocroller/lib/include/rocRoller/CodeGen/ArgumentLoader.hpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

141 lines
5.0 KiB
C++

// Copyright Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
/**
*/
#pragma once
#include <string>
#include <unordered_map>
#include <rocRoller/AssemblyKernelArgument.hpp>
#include <rocRoller/AssemblyKernel_fwd.hpp>
#include <rocRoller/CodeGen/Instruction.hpp>
#include <rocRoller/InstructionValues/Register_fwd.hpp>
#include <rocRoller/Utilities/Generator.hpp>
namespace rocRollerTest
{
class ArgumentLoaderTest_loadArgExtra_Test;
}
namespace rocRoller
{
/**
* Generates code to load argument values from the kernel argument buffer into SGPRs.
* Supports two main strategies: all-at-once, and on-demand.
*
* All-at-once can be faster since we can use wider load instructions, but so far this
* requires allocating all the argument SGPRs in one block so they can't be freed one by one
* to allow reuse.
*
* On-demand is more flexible, but also potentially slower as it will require more load
* instructions as well as possibly more synchronization.
*
*/
class ArgumentLoader
{
public:
ArgumentLoader(AssemblyKernelPtr kernel);
/**
* Loads all manually loaded arguments into a single allocation of SGPRs. Uses the
* widest load instructions possible given alignment constraints.
*/
Generator<Instruction> eagerLoadArguments();
/**
* Obtain the `Value` for a given argument. If the argument has not been loaded yet,
* emits instructions to load it into SGPRs.
*
* @param argName
* @param value
*/
Generator<Instruction> getValue(std::string const& argName, Register::ValuePtr& value);
void releaseArgument(std::string const& argName);
void releaseAllArguments();
Generator<Instruction>
loadRange(int offset, int sizeBytes, Register::ValuePtr& value) const;
/**
* Allocates the block of registers that will be preloaded with kernel arguments at the
* beginning of the kernel execution. This must be called at the correct time within
* AllocateInitialRegisters as it is part of the initial register state.
*
* Returns the appropriate values for the kernel description fields
* kernarg_preload_offset and kernarg_preload_length through preloadOffset and
* preloadLength respectively.
*/
Generator<Instruction> allocatePreloadedRegisters(int& preloadOffset, int& preloadLength);
bool anyPreloadedArguments() const;
bool anyManuallyLoadedArguments() const;
/**
* Decides which if any kernel arguments can be preloaded based on architecture and
* kernel options.
*
* The priority is to pick the earliest arguments first, but it will pick out-of-order
* arguments if alignment prevents earlier arguments from being preloaded.
*
* `args` will be partitioned into preloaded and non-preloaded arguments, and then
* sorted descending by size.
*/
void decidePreloadedKernargs(std::vector<AssemblyKernelArgument>& args);
/**
* Splits the block allocations of kernel arguments into individual registers and clears
* the block allocations so that individual kernel arguments can be deallocated individually.
*/
Generator<Instruction> splitOutArgumentRegisters();
private:
friend class rocRollerTest::ArgumentLoaderTest_loadArgExtra_Test;
std::weak_ptr<Context> m_context;
AssemblyKernelPtr m_kernel;
Generator<Instruction> loadArgument(std::string const& argName);
Generator<Instruction> loadArgument(AssemblyKernelArgument const& arg);
/// Call the one from the AssemblyKernel instead.
Register::ValuePtr argumentPointer() const;
Generator<Instruction> splitOutArgs(Register::ValuePtr rawRegs, int beginOffset);
std::unordered_map<std::string, Register::ValuePtr> m_loadedValues;
Register::ValuePtr m_preloadedBlock;
Register::ValuePtr m_manuallyLoadedBlock;
int m_manuallyLoadedOffset = 0;
void populateAnyArgumentsFlags() const;
mutable std::optional<bool> m_anyPreloadedArguments;
mutable std::optional<bool> m_anyManuallyLoadedArguments;
};
/**
* Picks the widest load instruction to load some of argPtr[offset:endOffset]
* into s[*beginReg:*endReg]. Returns the width of that load instruction in
* bytes, or 0 if offset == endOffset.
*
* Reasons to decrease the width of the load:
* - offset is not aligned to the width of the load
* - endOffset-offset is less than the width of the load
* - *beginReg is not aligned to the width of the load
* - destination registers are not contiguous
*
* @return int Width of the load in bytes
*/
template <typename Iter, typename End>
inline int PickInstructionWidthBytes(int offset, int endOffset, Iter beginReg, End endReg);
}
#include <rocRoller/CodeGen/ArgumentLoader_impl.hpp>