使用 MPI 做 3D 带状矩阵的转置

news2024/12/27 12:41:04

目的:整个大矩阵从 [Nx, Ny, Nz] 转到 [Nz, Nx, Ny]

每个进程的输入:大矩阵的 [Nx / total_proc_num, Ny, Nz] 的部分

每个进程的输出:大矩阵的 [Nz / total_proc_num, Nx, Ny] 的部分

一开始我大概有一个想法,假设两个进程的话,就把整个大矩阵分成 4 * 4 的块,进行分配,但是我不知道怎么分,就算是把转置之前的数据分布和转置之后的数据分布写出来了,也似乎找不到规律。

我做的图

xyz

在这里插入图片描述

zxy

在这里插入图片描述

后面通过 chatgpt 做出来了

#include <algorithm>
#include <iostream>
#include <mpi.h>
#include <vector>

void transpose_3d_block(int* local_A, int* local_A_T, int local_nx, int Ny, int Nz)
{
    for (int i = 0; i < local_nx; ++i)
    {
        for (int j = 0; j < Ny; ++j)
        {
            for (int k = 0; k < Nz; ++k)
            {
                local_A_T[k * local_nx * Ny + i * Ny + j] = local_A[i * Ny * Nz + j * Nz + k];
            }
        }
    }
}

int main(int argc, char** argv)
{
    MPI_Init(&argc, &argv);

    int rank, size;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    // 矩阵维度
    const int Nx = 4, Ny = 6, Nz = 8;
    const int local_nx     = Nx / size;
    const int new_local_nx = Nz / size;

    // 创建局部数据块
    std::vector<int> local_A(local_nx * Ny * Nz);
    std::vector<int> local_A_T(new_local_nx * Nx * Ny);

    // 初始化矩阵,仅在主进程上进行
    if (rank == 0)
    {
        std::vector<int> A(Nx * Ny * Nz);
        for (int i = 0; i < Nx * Ny * Nz; ++i)
        {
            A[i] = i;
        }

        // 分割矩阵到各个进程
        for (int i = 0; i < size; ++i)
        {
            if (i == 0)
            {
                std::copy(A.begin(), A.begin() + local_nx * Ny * Nz, local_A.begin());
            }
            else
            {
                MPI_Send(A.data() + i * local_nx * Ny * Nz, local_nx * Ny * Nz, MPI_INT, i, 0, MPI_COMM_WORLD);
            }
        }
    }
    else
    {
        MPI_Recv(local_A.data(), local_nx * Ny * Nz, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    }

    // 局部转置 (local_nx, Ny, Nz) -> (Nz, local_nx, Ny)
    transpose_3d_block(local_A.data(), local_A_T.data(), local_nx, Ny, Nz);

    // 准备交换数据
    std::vector<int> send_data(local_A_T);
    std::vector<int> recv_data(send_data.size());

    // 交换数据
    MPI_Alltoall(send_data.data(),
                 new_local_nx * local_nx * Ny,
                 MPI_INT,
                 recv_data.data(),
                 new_local_nx * local_nx * Ny,
                 MPI_INT,
                 MPI_COMM_WORLD);

    // 重组数据到local_result
    std::vector<int> local_result(new_local_nx * Nx * Ny);
    for (int i = 0; i < size; ++i)
    {
        for (int j = 0; j < new_local_nx; ++j)
        {
            std::copy(recv_data.begin() + (i * new_local_nx + j) * local_nx * Ny,
                      recv_data.begin() + (i * new_local_nx + j + 1) * local_nx * Ny,
                      local_result.begin() + j * Nx * Ny + i * local_nx * Ny);
        }
    }

    // 输出转置结果,仅在主进程上进行检查
    if (rank == 0)
    {
        std::vector<int> A_T(Nz * Nx * Ny);
        std::copy(local_result.begin(), local_result.begin() + new_local_nx * Nx * Ny, A_T.begin());
        for (int i = 1; i < size; ++i)
        {
            MPI_Recv(A_T.data() + i * new_local_nx * Nx * Ny,
                     new_local_nx * Nx * Ny,
                     MPI_INT,
                     i,
                     0,
                     MPI_COMM_WORLD,
                     MPI_STATUS_IGNORE);
        }

        std::cout << "Transposed matrix A_T:" << std::endl;
        for (int i = 0; i < Nz; ++i)
        {
            for (int j = 0; j < Nx; ++j)
            {
                for (int k = 0; k < Ny; ++k)
                {
                    std::cout << A_T[i * Nx * Ny + j * Ny + k] << " ";
                }
                std::cout << std::endl;
            }
            std::cout << std::endl;
        }
    }
    else
    {
        MPI_Send(local_result.data(), new_local_nx * Nx * Ny, MPI_INT, 0, 0, MPI_COMM_WORLD);
    }

    MPI_Finalize();
    return 0;
}

输出:

Transposed matrix A_T:
0 8 16 24 32 40 
48 56 64 72 80 88 
96 104 112 120 128 136 
144 152 160 168 176 184 

1 9 17 25 33 41 
49 57 65 73 81 89 
97 105 113 121 129 137 
145 153 161 169 177 185 

2 10 18 26 34 42 
50 58 66 74 82 90 
98 106 114 122 130 138 
146 154 162 170 178 186 

3 11 19 27 35 43 
51 59 67 75 83 91 
99 107 115 123 131 139 
147 155 163 171 179 187 

4 12 20 28 36 44 
52 60 68 76 84 92 
100 108 116 124 132 140 
148 156 164 172 180 188 

5 13 21 29 37 45 
53 61 69 77 85 93 
101 109 117 125 133 141 
149 157 165 173 181 189 

6 14 22 30 38 46 
54 62 70 78 86 94 
102 110 118 126 134 142 
150 158 166 174 182 190 

7 15 23 31 39 47 
55 63 71 79 87 95 
103 111 119 127 135 143 
151 159 167 175 183 191

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1692622.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

24款奔驰GLE350升级原厂环视全景360影像 抬头显示HUD

奔驰GLE350原厂360全景影像的清晰度通常取决于车辆的具体型号和年份&#xff0c;以及安装的摄像头和显示屏质量。一般来说&#xff0c;原厂360全景影像系统会提供高清的影像&#xff0c;让驾驶者能够清晰地看到车辆周围的环境&#xff0c;帮助进行停车和转弯等操作抬头显示&…

go学习笔记-从圣经中抄录的接口值的思考

接口值 接口值&#xff0c;由两个部分组成&#xff0c;一个具体的类型和那个类型的值 下面4个语句中&#xff0c;变量w得到了3个不同的值。&#xff08; 开始和最后的值是相同的&#xff09; var w io.Writer w os.Stdout w new(bytes.Buffer) w nil var w io.Writer var…

胶原蛋白流失大揭秘:你的肌肤还年轻吗?

&#x1f343;当我们谈及胶原蛋白&#xff0c;不少女生眼中都会闪过一丝光芒。为什么呢&#xff1f;因为胶原蛋白是维持我们肌肤弹性、水润的秘密武器啊&#xff01;但是&#xff0c;随着岁月的流逝&#xff0c;你是否发现自己的肌肤开始变得松弛、无弹性&#xff0c;甚至出现了…

夸夸生肖属鼠的女性朋友

属鼠人一生的命运受到许多因素的影响&#xff0c;包括性格、家庭、教育、环境等。属鼠人性格外向、求知欲强、善解人意、善于结交各种各样的朋友&#xff0c;有丰富的人脉&#xff0c;容易得到他人的帮助和支持。 属鼠的人聪明、机智&#xff0c;他们善于观察&#xff0c;富有…

手把手教学,一站式安装ubuntu及配置服务器

应用背景&#xff1a;实验室刚弄了一台4090的电脑&#xff0c;老师让我们搞成服务器 一、制作ubuntu启动盘 1.1 清华开源影像站下载ubuntu桌面版本Index of /ubuntu-releases/22.04/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 1.2 下载UltralSO软件 https://…

案例分享|Alluxio在自动驾驶模型训练中的应用与部署

分享嘉宾&#xff1a; 杨林三-辉羲智能 关于辉羲智能&#xff1a; 辉羲智能致力打造创新车载智能计算平台&#xff0c;提供高阶智能驾驶芯片、易用开放工具链及全栈自动驾驶解决方案&#xff0c;运用独创性“数据闭环定义芯片”方法学&#xff0c;助力车企构建低成本、大规模和…

Java延时队列取消未支付的订单

一、定义延迟任务类 package com.activity.domain;import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit;/*** 延迟任务类*/ public class DelayedCancellation implements Delayed {private String order;private final long delayTime; // 延迟时间p…

Ansible自动化运维中的Setup收集模块应用详解

作者主页&#xff1a;点击&#xff01; Ansible专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年5月22日13点14分 &#x1f4af;趣站推荐&#x1f4af; 前些天发现了一个巨牛的&#x1f916;人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xf…

捕食者优化算法,原理详解,MATLAB代码免费获取

捕食者优化算法&#xff08;Hunter–prey optimization&#xff0c;HPO&#xff09;是一种受自然启发的群智能优化算法。该算法的灵感来自于捕食动物(如狮子、豹和狼)以及猎物(如雄鹿和瞪羚)的行为。动物狩猎行为有很多场景&#xff0c;其中一些场景已经转化为优化算法。本文使…

数据结构篇其三---链表分类和双向链表

​ 前言 数据结构篇其二实现了一个简单的单链表&#xff0c;链表的概念&#xff0c;单链表具体实现已经说明&#xff0c;如下&#xff1a; 单链表 事实上&#xff0c;前面的单链表本质上是无头单向不循环链表。此篇说明的双向链表可以说完全反过来了了。无论是之前的单链表还…

Arthas反编译与重新加载class

一、背景 因为其他研发部门同事给的产品jar包存在一个问题&#xff0c;就是http底层的超时时间默认为60s&#xff0c;但是最近调用外部接口同步数据&#xff0c;这个数据量太大导致超时超过60s&#xff0c;每次同步都不成功。但是客户目前对此情况特别不满意&#xff0c;需要紧…

将电脑D盘部分空间划分给C盘的方法

本文介绍在Windows电脑中&#xff0c;将D盘的部分空间分给C盘的方法。 最近&#xff0c;发现电脑中C盘的空间剩余不多了&#xff1b;而D盘由于当初分盘时划分的空间过多&#xff0c;导致其剩余空间很大且大概率以后都不会用上D盘中这些多余的空间了。因此&#xff0c;希望将D盘…

使用Word表格数据快速创建图表

实例需求&#xff1a;Word的表格如下所示&#xff0c;标题行有合并单元格。 现在需要根据上述表格数据&#xff0c;在Word中创建如下柱图。如果数据在Excel之中&#xff0c;那么创建这个图并不复杂&#xff0c;但是Word中就没用那么简单了&#xff0c;虽然Word中可以插入图表&a…

轻松拿捏C语言——【字符串函数】的使用及模拟实现

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 感谢 目录 一、…

向npm发布自己写的vue组件,使用vite创建项目

向npm发布自己写的vue组件&#xff0c;使用vite创建项目 创建项目 pnpm create vite输入项目名称 由于我的组件是基于 ant-design-vue和vue的&#xff0c;需要解析.vue文件&#xff0c;我又安装了下面4个。 然后执行 pnpm i安装依赖 vite.config.ts import { defineC…

ES基础概念

本文不介绍如何使用ES&#xff08;使用ES见&#xff1a;&#xff09; 1.ES生态圈 ES&#xff1a; Logstash&#xff1a;数据处理服务程序&#xff0c;解析转换加工数据&#xff1b; Kibana&#xff1a;数据展示、集群管理&#xff0c;数据可视化、ES管理与监控、报表等&#xf…

【QT+VS】如何在现有VS项目中添加Qt界面?【全网最详细】

0. 前置步骤 参考如下链接文章中的 前3个步骤(1:下载Qt;2:安装Qt;3:安装Qt插件),完成环境的配置和安装。 深耕AI:如何联合Qt,VS,C++,来开发一个电脑版软件(简单有趣,详细) 本文的基础项目链接为: c++工程+图像分割预测+mmdet+实例分割+最新工程+简洁易懂+新手…

方正畅享全媒体新闻采编系统 binary.do SQL注入漏洞复现

0x01 产品简介 方正畅享全媒体新闻生产系统是以内容资产为核心的智能化融合媒体业务平台,融合了报、网、端、微、自媒体分发平台等全渠道内容。该平台由协调指挥调度、数据资源聚合、融合生产、全渠道发布、智能传播分析、融合考核等多个平台组成,贯穿新闻生产策、采、编、发…

Mysql 备份恢复 mysqldump与xtrabackup备份

1.1 备份的原因 备份是数据安全的最后一道防线&#xff0c;对于任何数据丢失的场景&#xff0c;备份虽然不一定能恢复百分之百的数据 (取决于备份周期)&#xff0c;但至少能将损失降到最低。衡量备份恢复有两个重要的指标&#xff1a;恢复点目标(RPO) 和恢复时间目标(RTO)&…

1.freertos基础知识

1.freertos最核心的概念就是多线程&#xff0c;就是可以让两段代码同时进行。 2.针对不同的用户场景&#xff0c;freertos提供了4种交互方式&#xff1a;消息队列&#xff0c;任务通知&#xff0c;信号量&#xff0c;互斥锁 3.什么是API&#xff1f;API是应用程序编程接口&…