una programacion hacer estructuras estructurada estructura ats atc arreglo anidadas struct mpi

hacer - programacion ats struct



serialización de estructuras en C y transferencia sobre MPI (3)

Aunque la respuesta de Jonathan Dursi es correcta, es demasiado complicada. MPI proporciona constructores de tipo más simples y menos generales más adecuados para su problema. MPI_Type_create_struct SOLO se necesita cuando tiene diferentes tipos de base (por ejemplo, un int y un float).

Para su ejemplo, existen varias soluciones mejores:

  • Suponiendo que los dos enteros están alineados en un área de memoria contigua (es decir, como una matriz de enteros), no necesita un tipo de datos derivado en absoluto. Simplemente envíe / reciba dos elementos de tipo MPI_INT con la dirección de una variable de tipo car que se utilizará como el búfer de envío / recepción:

    MPI_Send(&send, 2, MPI_INT, dest, tag, MPI_COMM_WORLD); MPI_Recv(&recv, 2, MPI_INT, src, tag, MPI_COMM_WORLD, &status);

  • Si desea utilizar un tipo de datos derivado (por ejemplo, para la legibilidad o por el MPI_Type_contiguous de hacerlo), puede usar MPI_Type_contiguous que corresponde a las matrices:

    MPI_Type_contiguous(2, MPI_INT, &mpi_car_type);

  • En caso de que los dos enteros estén alineados de manera diferente (lo más probable es que no sea el caso, pero depende de la máquina y existen implementaciones de MPI para muchas plataformas diferentes), puede usar MPI_Type_indexed_block : toma una matriz de desplazamientos (como MPI_Type_create_struct ), pero solo un argumento de tipo antiguo y la longitud de bloque de cada bloque es 1 por definición:

    MPI_Aint offsets[2]; offsets[0] = offsetof(car, shifts) ; //most likely going to be 0 offsets[1] = offsetof(car, topSpeed); MPI_Type_indexed_block(2, offsets, MPI_INT);

Mientras que la otra solución es semánticamente correcta, es mucho más difícil de leer y puede incurrir en una gran penalización de rendimiento.

He definido una estructura personalizada y quiero enviarla a otro proceso MPI utilizando MPI_Bsend (o MPI_Send).

Aquí está mi estructura:

struct car{ int shifts; int topSpeed; }myCar;

Sin embargo, aparte de los tipos primitivos, MPI no parece apoyar la "transmisión" directa de tipos de datos complejos como la estructura anterior. He oído que podría tener que usar "serialización". ¿Cómo debo hacerlo y enviar ''myCar'' para procesar 5?


Jeremiah tiene razón: MPI_Type_create_struct es el camino a seguir aquí.

Es importante recordar que MPI es una biblioteca, no está integrada en el lenguaje; por lo tanto, no puede "ver" cómo se ve una estructura para serializarla por sí misma. Entonces, para enviar tipos de datos complejos, debe definir explícitamente su diseño. En un lenguaje que tiene soporte nativo para la serialización, un conjunto de envoltorios MPI puede hacer uso de eso; mpi4py por ejemplo, utiliza pickle de Python para enviar de forma transparente tipos de datos complejos; pero en C, tienes que arremangarte y hacerlo tú mismo.

Para su estructura, se ve así:

#include <stdio.h> #include <stdlib.h> #include <mpi.h> #include <stddef.h> typedef struct car_s { int shifts; int topSpeed; } car; int main(int argc, char **argv) { const int tag = 13; int size, rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size < 2) { fprintf(stderr,"Requires at least two processes./n"); exit(-1); } /* create a type for struct car */ const int nitems=2; int blocklengths[2] = {1,1}; MPI_Datatype types[2] = {MPI_INT, MPI_INT}; MPI_Datatype mpi_car_type; MPI_Aint offsets[2]; offsets[0] = offsetof(car, shifts); offsets[1] = offsetof(car, topSpeed); MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_car_type); MPI_Type_commit(&mpi_car_type); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { car send; send.shifts = 4; send.topSpeed = 100; const int dest = 1; MPI_Send(&send, 1, mpi_car_type, dest, tag, MPI_COMM_WORLD); printf("Rank %d: sent structure car/n", rank); } if (rank == 1) { MPI_Status status; const int src=0; car recv; MPI_Recv(&recv, 1, mpi_car_type, src, tag, MPI_COMM_WORLD, &status); printf("Rank %d: Received: shifts = %d topSpeed = %d/n", rank, recv.shifts, recv.topSpeed); } MPI_Type_free(&mpi_car_type); MPI_Finalize(); return 0; }