使用MPI-IO并行读写HDF5文件

使用MPI-IO并行读写HDF5文件

HDF5支持通过MPI-IO进行并行读写,这对于大规模科学计算应用非常重要。下面我将提供C++和Fortran的示例程序,展示如何使用MPI-IO并行读写HDF5文件。

准备工作

在使用MPI-IO的HDF5之前,需要确保:

  1. HDF5库编译时启用了MPI支持
  2. 程序链接了HDF5的MPI库

C++示例

#include <hdf5.h>
#include <mpi.h>
#include <iostream>
#include <vector>#define FILE_NAME "parallel.h5"
#define DATASET_NAME "IntArray"
#define DIM0 100  // 全局维度
#define DIM1 100int main(int argc, char** argv) {// 初始化MPIMPI_Init(&argc, &argv);int mpi_rank, mpi_size;MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);// 初始化HDF5的MPI环境hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS);H5Pset_fapl_mpio(plist_id, MPI_COMM_WORLD, MPI_INFO_NULL);// 创建或打开文件hid_t file_id = H5Fopen(FILE_NAME, H5F_ACC_RDWR, plist_id);if (file_id < 0) {file_id = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, plist_id);}H5Pclose(plist_id);// 定义数据集维度hsize_t dims[2] = {DIM0, DIM1};// 创建数据空间hid_t filespace = H5Screate_simple(2, dims, NULL);// 创建数据集hid_t dset_id = H5Dcreate(file_id, DATASET_NAME, H5T_NATIVE_INT, filespace,H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);H5Sclose(filespace);// 定义每个进程的写入区域hsize_t count[2] = {DIM0/mpi_size, DIM1};hsize_t offset[2] = {mpi_rank * count[0], 0};// 选择数据集的超平面filespace = H5Dget_space(dset_id);H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, count, NULL);// 创建内存数据空间hid_t memspace = H5Screate_simple(2, count, NULL);// 准备数据 - 每个进程填充自己的部分std::vector<int> data(count[0] * count[1]);for (size_t i = 0; i < count[0]; ++i) {for (size_t j = 0; j < count[1]; ++j) {data[i * count[1] + j] = mpi_rank * 1000 + i * count[1] + j;}}// 设置集体写入属性plist_id = H5Pcreate(H5P_DATASET_XFER);H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);// 并行写入数据herr_t status = H5Dwrite(dset_id, H5T_NATIVE_INT, memspace, filespace,plist_id, data.data());// 清理资源H5Dclose(dset_id);H5Sclose(filespace);H5Sclose(memspace);H5Pclose(plist_id);H5Fclose(file_id);// 读取示例 - 类似写入过程if (mpi_rank == 0) {std::cout << "数据写入完成,开始读取验证..." << std::endl;}// 重新打开文件和数据集file_id = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, plist_id);dset_id = H5Dopen(file_id, DATASET_NAME, H5P_DEFAULT);// 分配读取缓冲区std::vector<int> read_data(count[0] * count[1]);// 设置集体读取属性plist_id = H5Pcreate(H5P_DATASET_XFER);H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);// 选择相同的超平面filespace = H5Dget_space(dset_id);H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, count, NULL);// 并行读取数据status = H5Dread(dset_id, H5T_NATIVE_INT, memspace, filespace,plist_id, read_data.data());// 验证数据bool error = false;for (size_t i = 0; i < count[0] * count[1]; ++i) {if (read_data[i] != data[i]) {error = true;break;}}if (!error && mpi_rank == 0) {std::cout << "数据验证成功!" << std::endl;}// 清理资源H5Dclose(dset_id);H5Sclose(filespace);H5Sclose(memspace);H5Pclose(plist_id);H5Fclose(file_id);// 结束MPIMPI_Finalize();return 0;
}

Fortran示例

program parallel_hdf5_mpiuse hdf5use mpiimplicit noneinteger :: ierr, mpi_rank, mpi_sizeinteger(hid_t) :: file_id, dset_id, filespace, memspace, plist_idinteger(hsize_t), dimension(2) :: dims = (/100, 100/)  ! 全局维度integer(hsize_t), dimension(2) :: count, offsetinteger, allocatable :: data(:, :)integer :: i, jcharacter(len=*), parameter :: file_name = "parallel.h5"character(len=*), parameter :: dset_name = "IntArray"! 初始化MPIcall MPI_Init(ierr)call MPI_Comm_rank(MPI_COMM_WORLD, mpi_rank, ierr)call MPI_Comm_size(MPI_COMM_WORLD, mpi_size, ierr)! 初始化HDF5call h5open_f(ierr)! 设置文件访问属性为MPI-IOcall h5pcreate_f(H5P_FILE_ACCESS_F, plist_id, ierr)call h5pset_fapl_mpio_f(plist_id, MPI_COMM_WORLD, MPI_INFO_NULL, ierr)! 创建或打开文件call h5fopen_f(file_name, H5F_ACC_RDWR_F, file_id, ierr, access_prp=plist_id)if (ierr /= 0) thencall h5fcreate_f(file_name, H5F_ACC_TRUNC_F, file_id, ierr, access_prp=plist_id)endifcall h5pclose_f(plist_id, ierr)! 创建数据空间call h5screate_simple_f(2, dims, filespace, ierr)! 创建数据集call h5dcreate_f(file_id, dset_name, H5T_NATIVE_INTEGER, filespace, &dset_id, ierr)call h5sclose_f(filespace, ierr)! 定义每个进程的写入区域count(1) = dims(1)/mpi_sizecount(2) = dims(2)offset(1) = mpi_rank * count(1)offset(2) = 0! 选择数据集的超平面call h5dget_space_f(dset_id, filespace, ierr)call h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, offset, count, ierr)! 创建内存数据空间call h5screate_simple_f(2, count, memspace, ierr)! 准备数据 - 每个进程填充自己的部分allocate(data(count(1), count(2)))do i = 1, count(1)do j = 1, count(2)data(i, j) = mpi_rank * 1000 + (i-1)*count(2) + jend doend do! 设置集体写入属性call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, ierr)call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, ierr)! 并行写入数据call h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, data, count, ierr, &file_space_id=filespace, mem_space_id=memspace, &xfer_prp=plist_id)! 清理资源deallocate(data)call h5dclose_f(dset_id, ierr)call h5sclose_f(filespace, ierr)call h5sclose_f(memspace, ierr)call h5pclose_f(plist_id, ierr)call h5fclose_f(file_id, ierr)! 读取示例 - 类似写入过程if (mpi_rank == 0) thenprint *, "数据写入完成,开始读取验证..."endif! 重新打开文件和数据集call h5fopen_f(file_name, H5F_ACC_RDONLY_F, file_id, ierr, access_prp=plist_id)call h5dopen_f(file_id, dset_name, dset_id, ierr)! 分配读取缓冲区allocate(data(count(1), count(2)))! 设置集体读取属性call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, ierr)call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, ierr)! 选择相同的超平面call h5dget_space_f(dset_id, filespace, ierr)call h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, offset, count, ierr)! 并行读取数据call h5dread_f(dset_id, H5T_NATIVE_INTEGER, data, count, ierr, &file_space_id=filespace, mem_space_id=memspace, &xfer_prp=plist_id)! 验证数据 (这里简化为检查第一个元素)if (data(1,1) == mpi_rank * 1000 + 1 .and. mpi_rank == 0) thenprint *, "数据验证成功!"endif! 清理资源deallocate(data)call h5dclose_f(dset_id, ierr)call h5sclose_f(filespace, ierr)call h5sclose_f(memspace, ierr)call h5pclose_f(plist_id, ierr)call h5fclose_f(file_id, ierr)! 关闭HDF5call h5close_f(ierr)! 结束MPIcall MPI_Finalize(ierr)end program parallel_hdf5_mpi

编译和运行

对于C++程序:

mpicxx -o parallel_hdf5 parallel_hdf5.cpp -lhdf5 -lz
mpiexec -n 4 ./parallel_hdf5

对于Fortran程序:

mpif90 -o parallel_hdf5 parallel_hdf5.f90 -lhdf5_fortran -lhdf5 -lz
mpiexec -n 4 ./parallel_hdf5

关键点说明

  1. MPI初始化: 必须首先初始化MPI环境
  2. HDF5 MPI属性: 使用H5Pset_fapl_mpio设置文件访问属性
  3. 数据分区: 每个进程负责数据集的不同部分
  4. 超平面选择: 使用H5Sselect_hyperslab选择要读写的区域
  5. 集体操作: 使用H5Pset_dxpl_mpio设置集体I/O模式
  6. 并行一致性: 所有进程必须参与集体操作

这些示例展示了基本的并行读写操作,实际应用中可能需要更复杂的数据分区和访问模式。

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

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

相关文章

七、自动化概念篇

自动化测试概念 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常&#xff0c;在设计了测试用例并通过评审之后&#xff0c;由测试人员根据测试用例中描述的过程一步步执行测试&#xff0c;得到实际结果与期望结果的比较。在此过程中&#xff0c;为了节省人…

redis cluster 的通信机制

Redis Cluster 的通信机制是其分布式架构的核心&#xff0c;基于 Gossip 协议 和 Cluster Bus 实现节点间状态同步与数据协调。以下是其通信机制的核心要点&#xff1a; 二进制协议&#xff1a;数据以字节流形式编码&#xff08;如Protobuf、Thrift、MQTT、Gossip&#xff09;。…

CTF web入门之文件上传

知识点 产生文件上传漏洞的原因 原因: 对于上传文件的后缀名(扩展名)没有做较为严格的限制 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件) 对于web server对于上传…

PhotoShop学习09

1.弯曲钢笔工具 PhotoShop提供了弯曲钢笔工具可以直观地创建路径&#xff0c;只需要对分段推拉就能够进行修改。弯曲港币工具位于工具面板中的钢笔工具里&#xff0c;它的快捷键为P。 在使用前&#xff0c;可以把填充和描边选为空颜色&#xff0c;并打开路径选项&#xff0c;勾…

tsconfig.json配置不生效

说明一下我遇到的问题&#xff0c;这是我的配置文件代码的 {"compilerOptions": {"module": "none","target": "ES5","outFile": "./dist/bundle.js"} } 和我想象不同的是&#xff0c;我编译成 js 没…

源代码加密之零日攻击

# SDC沙盒&#xff1a;有效防御零日攻击的多层防护体系 在当今复杂多变的网络安全环境中&#xff0c;零日攻击已成为企业面临的重大威胁之一。零日攻击利用尚未被公众发现或尚未被软件供应商修复的漏洞进行攻击&#xff0c;具有极高的隐蔽性和破坏性。SDC沙盒作为一种先进的数…

记录一次TDSQL网关夯住故障

环境信息&#xff1a; TDSQL-MySQL同城双中心集群&#xff0c;集中式实例&#xff0c;一主三副本&#xff0c;每个中心两个db副本&#xff0c;每个中心一个VIP&#xff0c;V每个IP通过硬件做负载均衡指向该中心两个proxy&#xff0c;操作系统为麒麟v10 arm。 故障描述&#xf…

代码随想录八股训练营完结总结

&#xff01; 40天的训练营&#xff0c;我总结了自己完整的八股文&#xff0c;后续在面试过程中可以补充 很感谢这次训练营&#xff0c;真的高频&#xff0c;在面试中能击中60%以上&#xff0c;剩下的就靠平时的积累了。 感谢训练营的小伙伴&#xff0c;很多次想偷懒&#x…

VS Code 的 .S 汇编文件里面的注释不显示绿色

1. 确认文件语言模式 打开 .S 文件后&#xff0c;查看 VS Code 右下角的状态栏&#xff0c;确认当前文件的识别模式&#xff08;如 Assembly、Plain Text 等&#xff09;。如果显示为 Plain Text 或其他非汇编模式&#xff1a; 点击状态栏中的语言模式&#xff08;如 Plain Te…

iphone各个机型尺寸

以下是苹果&#xff08;Apple&#xff09;历代 iPhone 机型 的屏幕尺寸、分辨率及其他关键参数汇总&#xff08;截至 2023年10月&#xff0c;数据基于官方发布信息&#xff09;&#xff1a; 一、标准屏 iPhone&#xff08;非Pro系列&#xff09; 机型屏幕尺寸&#xff08;英寸…

VSCode写java时常用的快捷键

首先得先安好java插件 1、获取返回值 这里是和idea一样的快捷键的&#xff0c;都是xxxx.var 比如现在我new一个对象 就输入 new MbDo().var // 点击回车即可变成下面的// MbDo mbDo new MbDo()//以此类推get方法也可获取 mbDo.getMc().var // 点击回车即可变成下面的 // St…

相机内外参

文章目录 相机内参相机外参 相机的内外参是相机标定过程中确定的重要参数&#xff0c;用于建立图像像素坐标与实际世界坐标之间的关系。 相机内参 定义&#xff1a;相机内参是描述相机内部光学和几何特性的参数&#xff0c;主要包括焦距、主点坐标、像素尺度因子以及畸变系数等…

【视频目标分割论文集】Efficient Track Anything0000

github 摘要 视频对象分割和追踪任意目标领域出现了强大的工具——分割任意模型 2&#xff08;SAM 2&#xff09;。SAM 2 实现令人印象深刻的视频对象分割性能的关键组成部分包括用于帧特征提取的大型多阶段图像编码器&#xff0c;以及存储过去帧记忆上下文以辅助当前帧分割的…

CSS学习02 动态列数表格开发,解决多组数据布局与边框重合问题

概要 在前端开发中&#xff0c;表格常用于展示结构化数据。当数据组的字段数量不统一时&#xff08;如有的行包含 3 组数据&#xff0c;有的行包含 2 组或 1 组&#xff09;&#xff0c;传统固定列数的表格会出现结构错位、边框重合等问题。本文通过 HTML/CSS 规范方法&#x…

Spark-core编程总结

1.reduce‌ 功能‌&#xff1a;聚集RDD中的所有元素&#xff0c;先聚合分区内数据&#xff0c;再聚合分区间数据。 示例‌&#xff1a;rdd.reduce(__) 将RDD中的所有整数相加。 2.collect‌ 功能‌&#xff1a;在驱动程序中&#xff0c;以数组Array的形式返回数据集的所有元…

处理Long类型长度超长导致前端精度丢失问题

1&#xff0c;问题场景 后端返回的Long类型的数据&#xff0c;超10000000000000000&#xff0c;前端处理的时候&#xff0c;数据被截断了。比如tchId: 11073477511443988481&#xff0c; 前端根据tchId获取下一环节信息的时候&#xff0c;传的tchId变成了11073477511443988400&…

ONVIF/RTSP/RTMP协议EasyCVR视频汇聚平台RTMP协议配置全攻略 | 直播推流实战教程

在现代化的视频管理和应急指挥系统中&#xff0c;RTMP协议作为一种高效的视频流传输方式&#xff0c;正变得越来越重要。无论是安防监控、应急指挥&#xff0c;还是物联网视频融合&#xff0c;掌握RTMP协议的接入和配置方法&#xff0c;都是提升系统性能和效率的关键一步。 今天…

安徽京准:GPS北斗卫星时空信号安全防护装置(授时)介绍

安徽京准&#xff1a;GPS北斗卫星时空信号安全防护装置&#xff08;授时&#xff09;介绍 1、主要特点 ★信号加固功能&#xff1a; GPS/BDS单系统信号拒止情况下&#xff08;包含受到GPS L1欺骗干扰、GPS L1压制干扰、BDS B1欺骗干扰、BDS B1压制干扰&#xff09;&#xff…

探索原生JS的力量:自定义实现类似于React的useState功能

1.写在前面 本方案特别适合希望在历史遗留的原生JavaScript项目中实现简单轻量级数据驱动机制的开发者。无需引入任何框架或第三方库&#xff0c;即可按照此方法封装出类似于React中useState的功能&#xff0c;轻松为项目添加状态管理能力&#xff0c;既保持了项目的轻量性&am…

02.使用cline(VSCode插件)、continue(IDEA插件)、cherry-studio玩转MCP

文章目录 安装环境uv&#xff08;python&#xff09;为什么不用pip&#xff1f;安装 nvm&#xff08;nodejs&#xff09; cline插件window配置如下linux配置如下测试MCP&#xff1a;time现在几点了&#xff1f;伦敦现在几点了&#xff1f;当纽约是下午四点&#xff0c;那伦敦是…