Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

https://enccs.github.io/intermediate-mpi/derived-datatypes-pt2/#

MPI已经定义的类型

https://rookiehpc.org/mpi/docs/mpi_datatype/index.html
List of named predefined dataypes:
MPI_SIGNED_CHAR / MPI_UNSIGNED_CHAR
MPI_SHORT / MPI_UNSIGNED_SHORT
MPI_INT / MPI_UNSIGNED
MPI_LONG / MPI_UNSIGNED_LONG
MPI_LONG_LONG_INT (a.k.a MPI_LONG_LONG) / MPI_UNSIGNED_LONG_LONG
MPI_CHAR
MPI_WCHAR
MPI_FLOAT
MPI_DOUBLE
MPI_LONG_DOUBLE
MPI_INT8_T / MPI_UINT8_T
MPI_INT16_T / MPI_UINT16_T
MPI_INT32_T / MPI_UINT32_T
MPI_INT64_T / MPI_UINT64_T
MPI_C_BOOL
MPI_C_COMPLEX
MPI_C_FLOAT_COMPLEX
MPI_C_DOUBLE_COMPLEX
MPI_C_LONG_DOUBLE_COMPLEX
MPI_AINT
MPI_COUNT
MPI_OFFSET
MPI_BYTE
MPI_PACKED

List of datatypes for reduction functions MPI_MINLOC and MPI_MAXLOC:
MPI_SHORT_INT
MPI_LONG_INT
MPI_FLOAT_INT
MPI_DOUBLE_INT
MPI_LONG_DOUBLE_INT
MPI_2INT

自定义结构体类型举例

struct Pair {
 int first;
 char second;
};

// build up the typemap for Pair
// the type signature for Pair
MPI_Datatype typesig[2] = {MPI_INT, MPI_CHAR};
// how many of each type in a "block" of Pair
int block_lengths[2] = {1, 1};
// displacements of data members in Pair
MPI_Aint displacements[2],base_address;
// why not use pointer arithmetic directly? We cannot use pointer arithmetic to compute displacements. Always keep in mind that your program might be deployed on heterogeneous architectures: you have to program for correctness and portability.
MPI_Get_address(&my_pair.first, base_address);
displacements[0] = 0;
MPI_Get_address(&my_pair.second, &displacements[1]);
// ! note, can NOT use -
displacements[1] = MPI_Aint_diff(displacements[1], base_address); 

// create and commit the new type
MPI_Datatype mpi_pair;
MPI_Type_create_struct(2, block_lengths, displacements, typesig, &mpi_pair);
MPI_Type_commit(&mpi_pair);

// clean up after use
MPI_Type_free(&mpi_pair);

包括通信的举例
https://github.com/ENCCS/intermediate-mpi/blob/main/content/code/day-1/07_pokemon-type-create-struct/solution/pokemon-type-create-struct.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <mpi.h>

#define STRLEN 25

struct Pokemon {
  // name of pokemon attacking
  char name[STRLEN];
  // life points
  double life_points;
  // damage done by the attack
  int damage;
  // strength multiplier
  double multiplier;
};

int main(int argc, char *argv[]) {
  int rank;
  int size;

  struct Pokemon charizard;

  MPI_Init(&argc, &argv);

  MPI_Comm comm = MPI_COMM_WORLD;

  MPI_Comm_size(comm, &size);
  MPI_Comm_rank(comm, &rank);

  MPI_Datatype typesig[4] = {MPI_CHAR, MPI_DOUBLE, MPI_INT, MPI_DOUBLE};
  int block_lengths[4] = {STRLEN, 1, 1, 1};

  MPI_Aint base_address, displacements[4];

  MPI_Get_address(&charizard.name, &displacements[0]);
  base_address = displacements[0];
  displacements[0] = displacements[0] - base_address;

  MPI_Get_address(&charizard.life_points, &displacements[1]);
  displacements[1] = displacements[1] - base_address;

  MPI_Get_address(&charizard.damage, &displacements[2]);
  displacements[2] = displacements[2] - base_address;

  MPI_Get_address(&charizard.multiplier, &displacements[3]);
  displacements[3] = displacements[3] - base_address;

  MPI_Datatype mpi_pokemon;
  MPI_Type_create_struct(4, block_lengths, displacements, typesig,
                         &mpi_pokemon);

  MPI_Type_commit(&mpi_pokemon);

  if (rank == 0) {
    sprintf(charizard.name, "Charizard");
    charizard.life_points = 180.0;
    charizard.damage = 60;
    charizard.multiplier = 0.89;

    MPI_Bcast(&charizard, 1, mpi_pokemon, 0, comm);
  } else {
    // matching broadcast on all other processes.
    MPI_Bcast(&charizard, 1, mpi_pokemon, 0, comm);

    // did we get it right?
    printf("rank %d:\n", rank);
    printf("  pokemon = %s\n", charizard.name);
    printf("  life_points = %2.2f\n", charizard.life_points);
    printf("  damage = %d\n", charizard.damage);
    printf("  multiplier = %2.2f\n", charizard.multiplier);
  }

  MPI_Type_free(&mpi_pokemon);

  MPI_Finalize();

  return EXIT_SUCCESS;
}

评论