Я использую короткую оболочку 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
, если необходимо?