通用MPI代码

问题描述 投票:1回答:2

我想创建一个通用的MPI方法,让我们说一个特定对象的bcast。但我需要将原始类型转换为MPI_Data类型?知道怎么做吗?

template <typename T>
void bcast_data(std::vector<T> vec) 
{
...
}

我需要使用MPI_INT用于int,MPI_DOUBLE用于double,...所以我需要一个类型转换方法,我想创建一个可以给我MPI_datatypes的数据表枚举,但它需要将类型作为输入参数传递。

任何的想法 ?

谢谢

c++ generics mpi
2个回答
2
投票

您可以使用“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), ...);
}

1
投票

我使用过这样的东西,它绝对不是一个完整的答案,因为它留下了一些类型。但它适用于我的情况

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.