特征压缩稀疏矩阵的 MPI 接收和发送
MPI Receive and Send for Eigen compressed sparse matrix
发送和接收使用特征库定义的稀疏矩阵的最佳(最快(方法是什么?
目前,我正在仅使用非零元素创建一个值、行和列向量(来自预定义的稀疏矩阵(,并逐个发送/接收这 3 个向量。这些向量是简单的 std::vector
if (0 == myrank) {
Sz.insert(0,0) = 0.5; Sz.insert(1,1) = -0.5;
//------ preparing to send ----------
shape[0] = Sz.rows();
shape[1] = Sz.cols();
int size=Sz.nonZeros();
val.resize(size); inner.resize(size); outer.resize(size);
cout << "val-size = "<< val.size() << endl;
int counter=0;
for (int k=0; k<Sz.outerSize(); ++k) {
for (CrsMatrixType::InnerIterator it(Sz,k); it; ++it) {
val[counter]=it.value();
inner[counter]=it.col();
outer[counter]=it.row();
counter++;
}
}
assert(counter==size);
MPI_Send(&shape[0],2,MPI_INT,1, 100, MPI_COMM_WORLD);
MPI_Send(&size,1,MPI_INT,1, 101, MPI_COMM_WORLD);
MPI_Send(&val[0],size,MPI_DOUBLE,1, 102, MPI_COMM_WORLD);
MPI_Send(&inner[0],size,MPI_INT,1, 103, MPI_COMM_WORLD);
MPI_Send(&outer[0],size,MPI_INT,1, 104, MPI_COMM_WORLD);
}
后来,我使用
if (1 == myrank) {
//------ preparing to receive ----------
shape.resize(2);
int size;
MPI_Recv(&shape[0],2,MPI_INT,0, 100, MPI_COMM_WORLD, &status);
MPI_Recv(&size,1,MPI_INT,0, 101, MPI_COMM_WORLD, &status);
val.resize(size); inner.resize(size); outer.resize(size);
MPI_Recv(&val[0],size,MPI_DOUBLE,0, 102, MPI_COMM_WORLD, &status);
MPI_Recv(&inner[0],size,MPI_INT,0, 103, MPI_COMM_WORLD, &status);
MPI_Recv(&outer[0],size,MPI_INT,0, 104, MPI_COMM_WORLD, &status);
Sz.resize(shape[0],shape[1]);
Sz.reserve(size); // allocate room for nonzero elements only.
for (int k=0; k<Sz.outerSize(); ++k) {
Sz.coeffRef(inner[k],outer[k]) = val[k];
}
cout << "my RANK " << myrank << endl;
cout << Sz << endl;
}
并将它们添加到秩 1 的稀疏矩阵中。
有没有更好的方法可以做到这一点?谢谢。
我通常建议使用压缩形式来传输稀疏矩阵。并且无需将值复制到临时std::vector
中。
void sendSparseEigen(const Ref<const SparseMatrix<double>,StandardCompressedFormat>& mat) {
int rows=mat.rows, cols=mat.cols, nnz=mat.nonZeros();
assert(rows==mat.innerSize() && cols==mat.outerSize());
assert(mat.outerIndexPtr()[cols]==nnz);
int shape[3] = {rows, cols, nnz};
MPI_Send(shape ,3 ,MPI_INT, 1, 100, MPI_COMM_WORLD);
MPI_Send(mat.valuePtr() ,nnz ,MPI_DOUBLE,1, 101, MPI_COMM_WORLD);
MPI_Send(mat.innerIndexPtr(),nnz ,MPI_INT, 1, 102, MPI_COMM_WORLD);
MPI_Send(mat.outerIndexPtr(),cols,MPI_INT, 1, 103, MPI_COMM_WORLD);
}
void receiveSparseEigen(SparseMatrix<double> &out){
int shape[3];
MPI_Recv(shape,3,MPI_INT,0, 100, MPI_COMM_WORLD, &status);
int rows=shape[0], cols=shape[1], nnz=shape[2];
out.resize(rows, cols);
out.reserve(nnz);
MPI_Recv(out.valuePtr(), nnz, MPI_DOUBLE,0, 101, MPI_COMM_WORLD, &status);
MPI_Recv(out.innerIndexPtr(),nnz, MPI_INT,0, 102, MPI_COMM_WORLD, &status);
MPI_Recv(out.outerIndexPtr(),cols,MPI_INT,0, 103, MPI_COMM_WORLD, &status);
out.outerIndexPtr()[cols] = nnz;
}
免责声明:我不是 MPI 专家,我从您的示例中复制了所有与 MPI 相关的代码——显然您应该以某种方式处理 MPI 生成的所有可能错误。上面的代码未经测试。
相关文章:
- C++中高效的大型稀疏块压缩线性方程
- 嵌入方指针压缩已禁用
- C++使用整数的压缩数组初始化对象
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- 在C++中将函数压缩为两种方式
- MPI突然停止了对多个核心的操作
- 在C++中使用LZ4压缩目录
- 使用C++进行运行长度解压缩
- 为什么大多数 pair 实现默认不使用压缩(空基优化)?
- 设置 Visual Studio for MPI: 找不到标识符错误
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- C++ 如何将数组值解压缩为函数参数
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 在 Qt(C++) 中使用 QProcess 解压缩 - 提取目录问题
- 如何使用 MPI 的远程内存访问 (RMA) 功能并行化数据聚合?
- 重载 MPI 中的运算符 ()
- 浏览压缩文件与游览解压缩它们
- 直接 2D 呈现到命令列表和打印:图片压缩
- 特征压缩稀疏矩阵的 MPI 接收和发送