Jul 17, 2021 at 3:13pm UTC
I am trying to build a class for mpi send and receive. I made this class without using template. now I am trying to use template. in order to get the MPI_datatype I'm using a function which return a pointer to character. but when I call it in the main function I get this error. "mpi.obj : error LNK2019: unresolved external symbol "public: __thiscall MPI_CALL<unsigned int>::MPI_CALL<unsigned int>(void)" (??0?$MPI_CALL@I@@QAE@XZ) referenced in function _main"
the cpp file for the class is like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
#include "mpi_call.h"
#include "includes.h"
#include "typedefs.h"
template <class T>
MPI_CALL<T>::MPI_CALL()
{
sendto = 0;
receive = 0;
Vector_size = 0;
item = 0;
}
template <typename T>
const char * MPI_CALL<T>:: get_type()
{
switch (item) {
case 1:
char *type = "MPI_INT" ;
return type ;
break ;
case 2:
char *type = "MPI_FLOAT" ;
return type;
break ;
case 3:
char *type = "MPI_UNSIGNED" ;
return type ;
break ;
case 4:
char *type = "MPI_DOUBLE" ;
return type;
break ;
case 5:
char *type = "MPI_CHAR" ;
return type;
break ;
case 6:
char *type = "MPI_SHORT" ;
return type;
break ;
case 7:
char *type = "MPI_LONG" ;
return type;
break ;
case 8:
char *type = "MPI_UNSIGNED_LONG" ;
return type;
break ;
case 9:
char *type = "MPI_BYTE" ;
return type;
break ;
}
}
template <class T>
void MPI_CALL<T>::Send_to(size_t sendtoe,std::vector<T>& Vector)
{
size_t Vector_size = Vector.size();
MPI_Send(&Vector[0], Vector_size, type, sendto, 0, MPI_COMM_WORLD);
}
template <class T>
void MPI_CALL<T>::Recv_from(size_t receive,std::vector<T>& Vector)
{
MPI_Status status;
size_t Vector_size = Vector.size();
MPI_Recv(&Vector[0], Vector_size,type, receive, 0, MPI_COMM_WORLD, &status);
}
and in the main I define an object of this class like
1 2 3
MPI_CALL<size_t> call_for;
call_for.item = 3;
call_for.get_type();
any help would be appreciated.
Last edited on Jul 17, 2021 at 3:40pm UTC
Jul 17, 2021 at 3:21pm UTC
You can't separate template classes into headers and sources. Both the declaration and the definition must be visible at the point of instantiation or the compiler doesn't know how to generate the code.
Jul 17, 2021 at 3:42pm UTC
yes you're right. I moved the cpp file into header file
Last edited on Jul 17, 2021 at 3:58pm UTC
Jul 17, 2021 at 5:57pm UTC
In this case I can print the data type on screen, but it says invalid datatype.
then I changed the code like this,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
template <class T>
class MPI_CALL {
public :
int sendto;
int receive;
size_t Vector_size;
char name;
MPI_CALL()=default ;
MPI_Datatype get_type();
void Send_to(size_t sendto,std::vector<T>& Vector);
void Recv_from(size_t receive,std::vector<T>& Vector);
};
template <class T>
inline MPI_Datatype MPI_CALL<T>::get_type()
{
char name = typeid (T).name()[0];
switch (name) {
case 'i' :
return MPI_INT;
case 'f' :
return MPI_FLOAT;
case 'j' :
return MPI_UNSIGNED;
case 'd' :
return MPI_DOUBLE;
case 'c' :
return MPI_CHAR;
case 's' :
return MPI_SHORT;
case 'l' :
return MPI_LONG;
case 'm' :
return MPI_UNSIGNED_LONG;
case 'b' :
return MPI_BYTE;
}
return MPI_Datatype();
}
then
MPI_Send(&Vector[0], Vector_size, MPI_Datatype(), sendto, 0, MPI_COMM_WORLD);
again it says invalid data type, why is this happening?
Last edited on Jul 17, 2021 at 5:58pm UTC
Jul 17, 2021 at 6:26pm UTC
You're not calling get_type(). Note that the return value of typeid(T).name() is unspecified. You'd be better off with something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
template <typename T>
struct mpi_type{};
#define DEFINE_mpi_type(type, val) \
template <> \
struct mpi_type<type>{ \
static const MPI_Datatype value = val; \
}
DEFINE_mpi_type(int , MPI_INT);
DEFINE_mpi_type(unsigned int , MPI_UNSIGNED);
DEFINE_mpi_type(float , MPI_FLOAT);
//etc.
MPI_Send(&Vector[0], Vector_size, mpi_type<T>::value, sendto, 0, MPI_COMM_WORLD);
Last edited on Jul 17, 2021 at 6:27pm UTC
Jul 17, 2021 at 6:54pm UTC
thanks,but why i'm not calling get_type()?
Jul 17, 2021 at 6:58pm UTC
I wasn't telling you not to call get_type(), I was informing you that in your call to MPI_Send() you weren't calling get_type().
Jul 17, 2021 at 7:12pm UTC
I included the get_type() in send mpi but again it says invalid datatype
MPI_Send(&Vector[0], Vector_size, get_type(), sendto, 0, MPI_COMM_WORLD);
Last edited on Jul 17, 2021 at 7:13pm UTC
Jul 17, 2021 at 7:24pm UTC
Well, like I said, the return value of typeid(T).name() is unspecified. Are you sure your compiler returns what you think it returns?
Jul 17, 2021 at 7:49pm UTC
yes it's returning the type
if I defined something like const char* x=call_for.get_type()
then std::cout<<x<<std::endl;
it gives me the type
Last edited on Jul 17, 2021 at 7:56pm UTC