Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jul 3, 2025

Thanks for assigning this issue to me. I'm starting to work on it and will keep this PR's description up to date as I form a plan and make progress.

Original issue description:

As part of the runtime compilation implementation, when the client application collects an std::vector<JIT_Operation_pp> along a complex structure of classes like a graph, where each node has a generic interface type, and needs to return always the same type, like JIT_Operation_pp, we may fid our selves with a vector of JIT_Operations that contains one or more ReadBack operations, that need to be fused before they are fully defined and contain an exec() function to be called from within the Data Parallel Pattern.

We can not perform this process when having the vector of JIT_Operation_pp's because we can not convert from a runtime string to a compile time type. We need to compile the following function at runtime:

template <typename Read, typename Next, typename... IOps>
constexpr inline std::vector<JIT_Operation_pp> fuseBack(const Read& read, const Next& nextOp, const IOps&... iOps) {
    static_assert(!isReadType<Next>, "A Read Operation can not go after another Read Operation, it has to be ReadBack");
    if constexpr (sizeof...(iOps) > 0) {
        constexpr bool nextIsReadBack = isReadBackType<Next>;
        constexpr bool iOpsContainsReadBack = (isReadBackType<IOps> || ...);
        constexpr bool nextIsComputeOrMidWrite = isComputeType<Next> || isMidWriteType<Next>;
        if constexpr (nextIsReadBack || (nextIsComputeOrMidWrite && iOpsContainsReadBack)) {
            fuseReadsLaunchTransformDPP(tDPPDetails, fuse(read, nextOp), iOps...);
        } else {
            buildOperationPipeline(read, nextOp, iOps...);
        }
    } else {
        static_assert(isWriteType<Next>, "Last IOp must be WriteType");
        buildOperationPipeline(read, nextOp);
    }
}

Of course, we will not compile it, without knowing the types "Read" "Next" and "IOps...". Therefore, this function will be part of the included code, and we will need another function, also compiled at runtime, that takes as a parameter all the void* JIT_Operation_pp::opData pointers in the std::vector<JIT_Operation_pp> and internally casts each one of them to the type in std::string JIT_Operation_pp::opType as a const &. Then, it will call fuseBack() passing to it each one of the casted elements, and will return the resulting std::vector<JIT_Operation_pp>.

Now, we need a third function, this one compiled at compile time, that will build this second function, using the opType strings, pass it to the runtime compiler for compilation, and execute it.

All this, must be done with LLVM ORCv2, and LLVM ORCv2 must be linked with cmake.

All the new code must be placed in inlcude/fused_kernel/core/execution_model/executor_details/cpu_jit_details.h and a simple unit test must be aded to tests/JIT/test_cpu_jit.h and the resulting binaries will have to have the necessary parts of the LLVM library statically linked.

Please, do not create a build folder inside the repository, use a folder outside of it.

The work should be done in a branch that starts from branch 57

The resulting PR should try to merge to branch 57, not main

Fixes #64.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI requested a review from morousg July 3, 2025 10:21
@morousg morousg closed this Jul 3, 2025
@morousg morousg deleted the copilot/fix-64-2 branch July 3, 2025 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a CPU runtime compilation step, that allows to fuse the ReadBack operations present in an std::vector<JIT_Operation_pp>

2 participants