ソース 5.3.1 単純な汎用データ型 (C)

maindefs.h
#ifndef ___MAINDEFS_H__200211211819_JEWFJODSJF__INCLUDED___
#define ___MAINDEFS_H__200211211819_JEWFJODSJF__INCLUDED___

#include <mpi.h>

/* 配列の要素数を返します */
#define NUMOF(array)     (sizeof (array) / sizeof *(array))

/* 配列型の要素数を返します */
#define NUMOFT(type)     NUMOF(*(type*)0)

/* 配列型の文字列の長さを返します */
#define STRLEN(literal)  (NUMOF(literal) - 1)

#endif  /* #ifndef ___MAINDEFS_H__200211211819_JEWFJODSJF__INCLUDED___ */
newtype.h
#ifndef ___NEWTYPE_H__200211211820_DAOFIJE3W__INCLUDED___
#define ___NEWTYPE_H__200211211820_DAOFIJE3W__INCLUDED___

#include "maindefs.h"

/* int 2 個からなる新しい型です */
typedef int NEWTYPE_T[2];

/* MPI の新しいデータ型を作成、登録します */
void CreateNewType(MPI_Datatype* pNewType);

/* MPI の新しいデータ型を開放します */
void FreeNewType(MPI_Datatype* pNewType);

/* 新しい型の配列を乱数で初期化します */
void InitNewType(NEWTYPE_T* pNewType, int size);

/* 新しい型の配列を表示します */
void OutputNewType(NEWTYPE_T* pNewType, int size);

#endif  /* #ifndef ___NEWTYPE_H__200211211820_DAOFIJE3W__INCLUDED___ */
newtype.c
#include <stdio.h>
#include <stdlib.h>
#include "maindefs.h"
#include "newtype.h"

/* MPI の新しいデータ型を作成、登録します */
void CreateNewType(MPI_Datatype* pNewType)
{
  /* int 型 2 個からなる新しいデータ型を作成します */
  MPI_Type_contiguous(NUMOFT(NEWTYPE_T), MPI_INT, pNewType);

  /* その新しいデータ型を MPI が使用できるように登録します */
  MPI_Type_commit(pNewType);
}

/* MPI の新しいデータ型を開放します */
void FreeNewType(MPI_Datatype* pNewType)
{
  MPI_Type_free(pNewType);
}

/* 新しい型の配列を乱数で初期化します */
void InitNewType(NEWTYPE_T* pNewType, int size)
{
  int i, j;
  for(i = 0; i < size; ++i)
  { for(j = 0; j < NUMOF(pNewType[0]); ++j)
      { pNewType[i][j] = rand(); }
  }
}

/* 新しい型の配列を表示します */
void OutputNewType(NEWTYPE_T* pNewType, int size)
{
  int i, j;
  for(i = 0; i < size; ++i)
  {
     printf("  %d: <", i);
     for(j = 0; j < NUMOF(pNewType[0]); ++j)
     {
       if(j != 0)
         { printf(", "); }
       printf("%11d", pNewType[i][j]);
     }
     puts(">");
  }
}
main.c
#include <stdio.h>
#include "maindefs.h"
#include "newtype.h"

enum TAG_KIND   /* 通信タグ */
{
  TAG_NEWTYPE,  /* 新しいデータ型のテスト用通信タグ */
};
enum RANK_KIND  /* ランク */
{
  RANK_SENDER,  /* 送信側のランク */
  RANK_RECVER,  /* 受信側のランク */
};

/* 送信 */
void Send(MPI_Datatype newType)
{
  /* 送信するデータを作成し、出力します */
  NEWTYPE_T data[9];
  InitNewType(data, NUMOF(data));
  puts("Sended data    :");
  OutputNewType(data, NUMOF(data));

  /* データ型に newType を指定します */
  MPI_Send(data, NUMOF(data), newType,
           RANK_RECVER, TAG_HELLO, MPI_COMM_WORLD);
}

/* 受信 */
void Recv(MPI_Datatype newType)
{
  NEWTYPE_T data[64];
  int recvCount;
  MPI_Status status;

  /* データ型に newType を指定します */
  MPI_Recv(data, NUMOF(data), newType,
           RANK_SENDER, TAG_HELLO, MPI_COMM_WORLD, &status);
  MPI_Get_count(&status, newType, &recvCount);

  printf("Received count : %d\n", recvCount);
  puts("Received data  :");
  OutputNewType(data, recvCount);
}

int main(int argc, char** argv)
{
  int rank;
  MPI_Datatype newType;  /* 新しい MPI のデータ型 */

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  CreateNewType(&newType);  /* 新しいデータ型を作成、登録します */
  switch(rank)
  {
  /* newType は値渡しで構いません */
  case RANK_SENDER: Send(newType); break;
  case RANK_RECVER: Recv(newType); break;
  }
  FreeNewType(&newType);  /* 新しいデータ型の登録を解除します */

  MPI_Finalize();

  printf("Exit : %d\n", rank);
}

Last update was done on 2002.11.14