secretflow/yacl

采用Context类实现两方同步传输

Closed this issue · 16 comments

怎么在两方使用yacl/link/context文件中的Send Recv函数实现同步传输,需要多次传输二维的unsigned char数组数据,在这遇到了困难,希望作者给一些思路,谢谢

可以简单贴一下你的尝试代码嘛?thx

简单写了一个传输的例子

#include "context.h"
#include

// 将Buffer转换为二维数组
void BufferToArray(const yacl::Buffer& buffer, unsigned char array[10][10]) {
std::memcpy(array, buffer.data(), 100);
}

int main() {
// 创建Context对象
yacl::link::ContextDesc desc;
// 初始化desc
// ...

std::vector<std::shared_ptr<yacl::link::transport::IChannel>> channels;
// 初始化channels
// ...

std::shared_ptr<yacl::link::transport::IReceiverLoop> msg_loop;
// 初始化msg_loop
// ...

yacl::link::Context serverContext(desc, 1, channels, msg_loop);

// 接收数据
yacl::Buffer received = serverContext.Recv(1, "tag");

// 将接收到的Buffer转换为二维数组
unsigned char array[10][10];
BufferToArray(received, array);

// 处理数组
// ...

// 将处理后的数组转换为Buffer并发送
yacl::Buffer buffer = ArrayToBuffer(array);
serverContext.Send(1, buffer, "tag");

return 0;

}

#include "context.h"
#include

// 将二维数组转换为Buffer
yacl::Buffer ArrayToBuffer(unsigned char array[10][10]) {
yacl::Buffer buffer(100);
std::memcpy(buffer.data(), array, 100);
return buffer;
}

int main() {
// 创建Context对象
yacl::link::ContextDesc desc;
// 初始化desc
// ...

std::vector<std::shared_ptr<yacl::link::transport::IChannel>> channels;
// 初始化channels
// ...

std::shared_ptr<yacl::link::transport::IReceiverLoop> msg_loop;
// 初始化msg_loop
// ...

yacl::link::Context clientContext(desc, 0, channels, msg_loop);

// 创建并初始化一个二维数组
unsigned char array[10][10] = { /* 初始化数据 */ };

// 将数组转换为Buffer并发送
yacl::Buffer buffer = ArrayToBuffer(array);
clientContext.Send(0, buffer, "tag");

// 接收处理后的数据
yacl::Buffer received = clientContext.Recv(0, "tag");

// 处理接收到的数据
// ...

return 0;

}

可以看下这个 comments 是否对你有帮助:#30 (comment)

以及,可以直接 ctx.Send(ctx->NextRank(), ByteContainerView(YOUR_ARRAY_PTR, YOUR_ARRAY_SIZE), "tag"); 的方式传输。参考这里:https://github.com/secretflow/yacl/blob/main/yacl/base/byte_container_view.h#L37

Receive 之后可以手动把 buffer memory copy 到一个 array 里应该就可以了

发送二维数组还用压缩为一维吗,而且unsigned char还用转换为byte类型吗

发送二维数组还用压缩为一维吗

最好可以压缩一下,secretflow/spu 在使用的时候也是类似的操作

而且unsigned char还用转换为byte类型吗

这个就不需要了,如果我没记错的话是 (void *) 不需要再转了

FYI,可以再进一步问一下,是在尝试用 Yacl 写 mpc 类似的运算嘛?

写的PSI,需要多次收发数据,还有个问题收到数据后buffer怎么转为二维,memcpy可以直接实现吗

tag可以指定数据标签吗

写的PSI,需要多次收发数据,还有个问题收到数据后buffer怎么转为二维,memcpy可以直接实现吗

我自己的建议是直接 new array 的时候就可以创造一个 1-dimmension array,后面就基于这个 1-d buffer array 进行操作(主要是目前 yacl 里面矩阵用的比较少,所以没有引入类似于 EGIEN 这类库)

tag可以指定数据标签吗

tag 只是 trace / debug 过程使用的,和通信应该是无关的 https://github.com/secretflow/yacl/blob/main/yacl/link/context.cc#L199

但是后面的操作要求必须二维,有没有方法buffer.data()转为二维的

最直观的,就是按照每一行把 buffer.data() + i * line_num memory copy 过去就可以了

感兴趣的话,可以加一下隐语小助手的微信哈~ 微信号:SecretFlow01 如果 PSI 的研发过程中有问题,或者有需求可以随时和小助手联系

但是后面的操作要求必须二维,有没有方法buffer.data()转为二维的

c/c++语言的多维数组,在内存中是连续分布存放的,在内存中没有一维二维的区分。发送方直接把整段内存发送给接收方,接收方将收到的数据复制到目标数组就行。

数组的内存布局:
http://www.fredosaurus.com/notes-cpp/arrayptr/23two-dim-array-memory-layout.html

Stale issue message. Please comment to remove stale tag. Otherwise this issue will be closed soon.