我想创建一个通用的MPI方法,让我们说一个特定对象的bcast。但我需要将原始类型转换为MPI_Data类型?知道怎么做吗?
template <typename T>
void bcast_data(std::vector<T> vec)
{
...
}
我需要使用MPI_INT用于int,MPI_DOUBLE用于double,...所以我需要一个类型转换方法,我想创建一个可以给我MPI_datatypes的数据表枚举,但它需要将类型作为输入参数传递。
任何的想法 ?
谢谢
您可以使用“type traits”惯用法来序列化通用对象T
。这为您提供了在不更改实现的情况下添加对新类型的支持的优势。
看看我多年前写的这个MPI包装器:https://github.com/motonacciu/mpp。
您想要定义类似以下的类型特征:
template <class T>
struct mpi_type_traits {
typedef T element_type;
typedef T* element_addr_type;
static inline MPI_Datatype get_type(T&& raw);
static inline size_t get_size(T& raw);
static inline element_addr_type get_addr(T& raw);
};
并为混凝土类型提供专业化,例如std::vector<T>
如下:
template <class T>
struct mpi_type_traits<std::vector<T>> {
typedef T element_type;
typedef T* element_addr_type;
static inline size_t get_size(std::vector<T>& vec) {
return vec.size();
}
static inline MPI_Datatype get_type(std::vector<T>&& vec) {
return mpi_type_traits<T>::get_type( T{} );
}
static inline element_addr_type get_addr(std::vector<T>& vec) {
return mpi_type_traits<T>::get_addr( vec.front() );
}
};
您需要做的最后一件事是实现您的MPI方法并使用类型特征,例如在调用MPI_Send
时:
template <class T>
void send(T &&value, ...) {
MPI_Send(mpi_type_traits<T>::get_addr(value),
mpi_type_traits<T>::get_size(value),
mpi_type_traits<T>::get_type(value), ...);
}
我使用过这样的东西,它绝对不是一个完整的答案,因为它留下了一些类型。但它适用于我的情况
template<typename T>
MPI_Datatype get_type()
{
char name = typeid(T).name()[0];
switch (name) {
case 'i':
return MPI_INT;
break;
case 'f':
return MPI_FLOAT;
break;
case 'j':
return MPI_UNSIGNED;
break;
case 'd':
return MPI_DOUBLE;
break;
case 'c':
return MPI_CHAR;
break;
case 's':
return MPI_SHORT;
break;
case 'l':
return MPI_LONG;
break;
case 'm':
return MPI_UNSIGNED_LONG;
break;
case 'b':
return MPI_BYTE;
break;
}
}