c++ - 带有 MPI 前向声明的标头
问题描述
我正在使用这样的简短 MPI 包装器:
#ifndef INC_MyLib_MPIWRAPPER_H
#define INC_MyLib_MPIWRAPPER_H
#include <mpi.h>
/* libMyLib MPI struct & macros */
namespace libMyLib{
extern int mpi_rank;
extern int mpi_nranks;
extern int mpi_msg;
extern int mpi_msg_;
extern MPI_Comm mpi_active_comm;
}
#define MPI_INIT MPI_Init(&argc, &argv); MPI_Comm_size( libMyLib::mpi_active_comm, &libMyLib::mpi_nranks ); MPI_Comm_rank( libMyLib::mpi_active_comm, &libMyLib::mpi_rank );
#define MPI_INIT_NULL MPI_Init(nullptr, nullptr); MPI_Comm_size( libMyLib::mpi_active_comm, &libMyLib::mpi_nranks ); MPI_Comm_rank( libMyLib::mpi_active_comm, &libMyLib::mpi_rank );
#define MPI_FINISH MPI_Finalize( );
#define MPI_INTERRUPT libMyLib::mpi_msg = 1; MPI_Allreduce(&libMyLib::mpi_msg, &libMyLib::mpi_msg_, 1, MPI_INT, MPI_SUM, libMyLib::mpi_active_comm);
#define MPI_ERROR_CHECK libMyLib::mpi_msg = 0; MPI_Allreduce(&libMyLib::mpi_msg, &libMyLib::mpi_msg_, 1, MPI_INT, MPI_SUM, libMyLib::mpi_active_comm);; if( libMyLib::mpi_msg_ > 0 ){throw std::runtime_error(" eror " );}
#endif //INC_MyLib_MPIWRAPPER_H
我想mpi.h
在这里摆脱依赖,所以我尝试添加这样的MPI
类型的前向声明:
#ifndef INC_MyLib_MPIWRAPPER_H
#define INC_MyLib_MPIWRAPPER_H
#include <mpi.h>
/* MPI forward declarations to remove MPI header dependency from API */
typedef int MPI_Comm;
typedef int MPI_Datatype;
#define MPI_INT ((MPI_Datatype)0x4c000405)
typedef int MPI_Op;
#define MPI_SUM (MPI_Op)(0x58000003)
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
#if defined(HAVE_VISIBILITY)
#define MPICH_API_PUBLIC __attribute__((visibility ("default")))
#else
#define MPICH_API_PUBLIC
#endif
int MPI_Finalize(void) MPICH_API_PUBLIC;
int MPI_Comm_size(MPI_Comm comm, int *size) MPICH_API_PUBLIC;
int MPI_Comm_rank(MPI_Comm comm, int *rank) MPICH_API_PUBLIC;
int MPI_Init(int *argc, char ***argv) MPICH_API_PUBLIC;
/* libMyLib MPI struct & macros */
namespace libMyLib{
extern int mpi_rank;
extern int mpi_nranks;
extern int mpi_msg;
extern int mpi_msg_;
extern MPI_Comm mpi_active_comm;
}
#define MPI_INIT MPI_Init(&argc, &argv); MPI_Comm_size( libMyLib::mpi_active_comm, &libMyLib::mpi_nranks ); MPI_Comm_rank( libMyLib::mpi_active_comm, &libMyLib::mpi_rank );
#define MPI_INIT_NULL MPI_Init(nullptr, nullptr); MPI_Comm_size( libMyLib::mpi_active_comm, &libMyLib::mpi_nranks ); MPI_Comm_rank( libMyLib::mpi_active_comm, &libMyLib::mpi_rank );
#define MPI_FINISH MPI_Finalize( );
#define MPI_INTERRUPT libMyLib::mpi_msg = 1; MPI_Allreduce(&libMyLib::mpi_msg, &libMyLib::mpi_msg_, 1, MPI_INT, MPI_SUM, libMyLib::mpi_active_comm);
#define MPI_ERROR_CHECK libMyLib::mpi_msg = 0; MPI_Allreduce(&libMyLib::mpi_msg, &libMyLib::mpi_msg_, 1, MPI_INT, MPI_SUM, libMyLib::mpi_active_comm);; if( libMyLib::mpi_msg_ > 0 ){throw std::runtime_error(" eror " );}
#endif //INC_MyLib_MPIWRAPPER_H
问题是,在一个代码中,我需要将此包装器与真正的mpi.h
标头结合起来,并且出现如下错误:
/usr/bin/ld: ../../lib/liblibMyLib.a(Reader.cpp.o): in function `libMyLib::Reader::read()':
Reader.cpp:(.text+0x10f3): undefined reference to `MPI_Allreduce(void const*, void*, int, int, int, int)'
/usr/bin/ld: Reader.cpp:(.text+0x1764): undefined reference to `MPI_Allreduce(void const*, void*, int, int, int, int)'
collect2: error: ld returned 1 exit status
虽然我能理解,但我很好奇是否有任何方法,如果需要,如何使前向声明能够使用包装器并将其与mpi.h
标头结合起来?
解决方案
我不知道你为什么要这样做,或者它是否能正常工作,但你现在观察到的特定错误是因为 MPI 是一个 C 库。
C++ 将 C 实体与 C++ 实体分开处理。因此,如果您MPI_Allreduce
在 C++ 代码中声明一个函数,它所引用的函数MPI_Allreduce
与您在 C 代码中使用相同声明时所获得的函数不同。
为了使名称引用 C 实体,您必须使用 C 语言链接声明它,这是通过
extern "C" {
// declarations go here
}
您可以查看mpi.h
它是否执行相同的操作。
推荐阅读
- javascript - 截屏时,Highcharts 从图例中隐藏非活动系列
- c++ - SFML 纹理变换(放大)
- mongodb - 如何使用 GoLang 在 MongoDB 中执行插入操作?
- html - 显示帮助文本时引导表单布局中断
- ubuntu - 在 Ubuntu 服务器上安装 Laravel 5.7 时出错
- acumatica - 在“RC”订单类型的销售订单中需要帮助
- eslint - 如何通过规则而不是文件获取 eslint 报告?
- android - Android标准化位图
- python - 使用 pyinstaller 摆脱 chromedirver 控制台窗口
- jquery - 如何在 javascript/jquery 中将 id 添加到 data-id 元素