Skip to content

Fabrics 2/2: Implementation of the fabrics API#266

Open
jonasohland wants to merge 52 commits intodmf-mxl:mainfrom
jonasohland:feature/fabrics/jonas/protocols
Open

Fabrics 2/2: Implementation of the fabrics API#266
jonasohland wants to merge 52 commits intodmf-mxl:mainfrom
jonasohland:feature/fabrics/jonas/protocols

Conversation

@jonasohland
Copy link
Contributor

@jonasohland jonasohland commented Dec 4, 2025

This is step 2 of merging the fabrics functionality into the main mxl repo. Now we would like to merge the code that implements the api in fabrics.h

Enables transfer of grains and slices using remote memory access, tcp and shared memory on supported hardware.

Future improvements will include audio support and capability management.

Makes #78 obsolete.

Closes #181

NOTE: You must use the following cmake configure flag to enable the Fabric's API build : -DMXL_ENABLE_FABRICS_OFI=on

@jonasohland jonasohland requested review from a team December 4, 2025 15:25
@jonasohland jonasohland force-pushed the feature/fabrics/jonas/protocols branch 3 times, most recently from d20cc77 to fb07fdd Compare December 4, 2025 15:36
@jonasohland jonasohland force-pushed the feature/fabrics/jonas/protocols branch from 7c3f830 to 8eefc1f Compare December 5, 2025 14:20
@mlefebvre1 mlefebvre1 linked an issue Dec 10, 2025 that may be closed by this pull request
@jonasohland jonasohland force-pushed the feature/fabrics/jonas/protocols branch from 083112b to 20f7c76 Compare December 10, 2025 15:20
Copy link
Collaborator

@KimonHoffmann KimonHoffmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this massive contribution!
I looked through everything except for the test implementation and the demo. Most of remarks refer to syntactical aspects.

Copy link
Collaborator

@KimonHoffmann KimonHoffmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this massive contribution!
I looked through everything except for the test implementation and the demo. Most of my remarks refer to syntactical aspects.

@jonasohland
Copy link
Contributor Author

Thanks for this massive contribution! I looked through everything except for the test implementation and the demo. Most of my remarks refer to syntactical aspects.

Thanks for looking through our code! We really appreciate the effort. I have addressed almost everything, I have only one or two questions and have left your comments regarding those unresolved.
Thanks!

Copy link
Collaborator

@KimonHoffmann KimonHoffmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you for addressing my comments!
I noticed two smaller things that still need addressing (use of bit_cast<> and constexpr vs. inline), but the rest looks great.

@jonasohland jonasohland force-pushed the feature/fabrics/jonas/protocols branch from 8f6b6d0 to 4dac926 Compare December 24, 2025 14:11
@jonasohland jonasohland force-pushed the feature/fabrics/jonas/protocols branch from b5509a7 to 4c4dcda Compare January 14, 2026 12:39
Copy link
Collaborator

@KimonHoffmann KimonHoffmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks for the updates!

@mlefebvre1 mlefebvre1 requested review from a team January 16, 2026 18:56
Copy link
Collaborator

@KimonHoffmann KimonHoffmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small comments on the four commits added since my last review.

Copy link
Contributor

@lapointejp lapointejp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems okay to me. Just a couple typos and wording things to check.
Thank you so very much for contributing this @jonasohland and @mlefebvre1.

@jonasohland jonasohland force-pushed the feature/fabrics/jonas/protocols branch from 6c0f2ee to 7e9060c Compare January 28, 2026 15:50
@pprayle
Copy link

pprayle commented Feb 3, 2026

I've run into a couple of issues while trying to get the mxl-fabrics-demo app to stream between initiator and target using the verbs provider.

I'm running on Ubuntu 22.04 with a Mellanox ConnectX 6 DX card. The various verbs packages are at version 2510.0.11-1, installed via Nvidia's doca-roce package version 3.2.1-044000.

I'm not sure if these issues could be fixed by modifying the environment (system packages, OS settings etc). However, I'm describing here the changes I made to the code to make it work for me.

The first error is when the initiator attempts to register the shared memory:

[error] [MemoryRegion.cpp:67] fi_mr_regattr failed: Bad address, code -14

This happens because the flow reader opens the shared memory in read-only mode, but the memory registration requests write access using FI_WRITE flag in RMAGrainEgressProtocolTemplate::registerMemory.

This issue can be temporarily fixed by changing the access mode in Instance::getFlowReader to READ_WRITE.
If this really is the only way to fix the issue, then I guess an additional parameter to the getFlowReader function would be required to specify the access mode?

The second issue is the target receives a value of 0 for the number of valid slices received. The log message shows the following:

[demo.cpp:564] Comitted grain with index=106101956356 current index=106101956357 validSlices=0 flags=0

The value of valid slices is received in the completion data which is handled by RMAGrainIngressProtocol.
In the function processCompletion, a request for the next completion data with the internal buffer is being posted to the endpoint, then the data in the internal buffer is being returned (before it's arrived).
This code snippet shows the issue (comments added by me):

Target::ReadResult RMAGrainIngressProtocol::processCompletion(Endpoint& ep, Completion const& completion)
{
    if (auto data = completion.tryData(); data)
    {
        if (_immDataBuffer)
        {
            // request the next completion data with the internal buffer
            ep.recv(immDataRegion());
            // return the data in the internal buffer (before it's arrived)
            return Target::ReadResult{_immDataBuffer->data};
        }
        else
        {
            return Target::ReadResult{data->data()};
        }
    }

    return {};
}

The issue can be fixed by always returning the data from the current completion, after posting a request for the next one:

Target::ReadResult RMAGrainIngressProtocol::processCompletion(Endpoint& ep, Completion const& completion)
{
    if (auto data = completion.tryData(); data)
    {
        if (_immDataBuffer)
        {
            ep.recv(immDataRegion());
        }

        return Target::ReadResult{data->data()};
    }

    return {};
}

@jonasohland
Copy link
Contributor Author

Hi! @pprayle

Thanks for your comment!
The second issue is clearly a bug, which we will fix.

To your first point:
We had the same issue on EFA, and their driver team is working on a fix for that. It seems like a similar problem exists for specific hardware/driver combination.
We have successfully tested initiators with read-only memory on Connect-X cards, so maybe this is fixed in an updated driver or firmware for your card?
Otherwise, we would need to file a bug report upstream.

Thanks!
Jonas

@jonasohland
Copy link
Contributor Author

@pprayle BTW,

Memory registration in libfabric with the FI_WRITE flag should not be the issue.
From the libfabric man pages:

FI_WRITE
              The memory buffer may be used as the source buffer for RMA write and atomic operations on the initiator side.  Note that from the viewpoint of the application, the endpoint is reading from
              the memory buffer and copying the data onto the network.

Michael Lefebvre and others added 22 commits February 11, 2026 22:06
Co-authored-by: Michael Lefebvre <michael.lefebvre.31@gmail.com>
Signed-off-by: Michael Lefebvre <michael.lefebvre@riedel.net>
Co-authored-by: Michael Lefebvre <michael.lefebvre.31@gmail.com>
Signed-off-by: Michael Lefebvre <michael.lefebvre@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
…emless interopability.

Co-authored-by: Michael Lefebvre <michael.lefebvre.31@gmail.com>
Signed-off-by: Michael Lefebvre <michael.lefebvre@riedel.net>
…ng the supplied domain instead of hardcoded /dev/shm.

Co-authored-by: Michael Lefebvre <michael.lefebvre.31@gmail.com>
Signed-off-by: Michael Lefebvre <michael.lefebvre@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
As reported by @pprayle

Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
@jonasohland jonasohland force-pushed the feature/fabrics/jonas/protocols branch from a6cecc7 to 0436f4e Compare February 11, 2026 21:06
Co-authored-by: Jonas Ohland <jonas.ohland@gmail.com>
Signed-off-by: Jonas Ohland (Riedel) <jonas.ohland@riedel.net>
Copy link
Collaborator

@KimonHoffmann KimonHoffmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small things I stumbled upon.

*/
MXL_EXPORT
mxlStatus mxlFabricsInitiatorRemoveTarget(mxlFabricsInitiator in_initiator, mxlTargetInfo const in_targetInfo);
mxlStatus mxlFabricsInitiatorRemoveTarget(mxlFabricsInitiator in_initiator, mxlFabricsTargetInfo const in_targetInfo);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could get rid of this const qualification, especially in the context of of this declaration. Feels free to keep it for the definition if it proves to be helpful there (even though I personally tend to not use them on by value arguments).

*/
MXL_EXPORT
mxlStatus mxlFabricsInitiatorAddTarget(mxlFabricsInitiator in_initiator, mxlTargetInfo const in_targetInfo);
mxlStatus mxlFabricsInitiatorAddTarget(mxlFabricsInitiator in_initiator, mxlFabricsTargetInfo const in_targetInfo);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could get rid of this const qualification, especially in the context of of this declaration. Feels free to keep it for the definition if it proves to be helpful there (even though I personally tend to not use them on by value arguments).

*/
MXL_EXPORT
mxlStatus mxlFabricsTargetInfoToString(mxlTargetInfo const in_targetInfo, char* out_string, size_t* in_stringSize);
mxlStatus mxlFabricsTargetInfoToString(mxlFabricsTargetInfo const in_targetInfo, char* out_string, size_t* in_stringSize);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could get rid of this const qualification of in_targetInfo, especially in the context of of this declaration. Feels free to keep it for the definition if it proves to be helpful there (even though I personally tend to not use them on by value arguments).

: _inner(entry)
{}

Completion::Token Completion::randomToken()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ist this called often? If yes this way of obtaining the token could prove quite expensive.

mxlFabricsRegionsFromUserBuffers(memoryRegions.data(), memoryRegions.size(), &outRegions);

return {outRegions, regions};
std::vector<Region> regions;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use auto with right hand type auto regions = std::vector<Region>{}.

};

// clang-format on
std::vector<Region> regions;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use auto with right hand type auto regions = std::vector<Region>{}.


bool TargetInfo::operator==(TargetInfo const& other) const noexcept
{
return fabricAddress == other.fabricAddress && remoteRegions == other.remoteRegions && id == other.id;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use parentheses around binary subexpressions.

auto regionObj = regionValue.get<picojson::object>();
auto addr = std::stoull(regionObj.at("addr").get<std::string>());
auto len = std::stoull(regionObj.at("len").get<std::string>());
auto rkey = std::stoull(regionObj.at("rkey").get<std::string>());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use a comment as to why those fields are not fetched as numeric values directly.

throw Exception::invalidArgument("Invalid provider specified");
}

uint64_t caps = FI_RMA | FI_REMOTE_WRITE;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the std:: qualified variant.

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.

Fabrics: PR Step 2: API implementation Fabrics: partial-grain transfer support

6 participants