C에서의 구조 직렬화 및 MPI를 통한 전송
사용자 지정을 정의했습니다.struct
다른 MPI 프로세스로 전송해야 합니다.MPI_Bsend
(또는)MPI_Send
).
구조는 다음과 같습니다.
struct car{
int shifts;
int topSpeed;
}myCar;
문제는 원시 유형을 제외하고 MPI가 위에 표시된 구조와 같은 복잡한 데이터 유형의 직접 "전송"을 지원하지 않는 것 같습니다.저는 "직렬화"를 사용해야 할 수도 있다고 들었습니다.
어떻게 접근하여 성공적으로 전송해야 합니까?myCar
5번 프로세스로?
예레미야 말이 맞아요 - MPI_Type_create_struct가 여기로 가는 길입니다.
MPI는 언어에 내장된 라이브러리가 아니라 라이브러리라는 점을 기억하는 것이 중요합니다. 따라서 MPI는 구조가 어떻게 생겼는지 직접 직렬화할 수 없습니다.따라서 복잡한 데이터 유형을 전송하려면 레이아웃을 명시적으로 정의해야 합니다.직렬화를 기본적으로 지원하는 언어에서는 MPI 래퍼 세트가 이를 사용할 수 있습니다. 예를 들어 mpi4py는 파이썬의 피클을 사용하여 복잡한 데이터 유형을 투명하게 전송하지만 C에서는 소매를 걷어붙이고 직접 해야 합니다.
구조의 경우 다음과 같습니다.
#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;
}
Jonathan Dursi의 대답이 맞긴 하지만, 너무 복잡합니다. MPI는 당신의 문제에 더 적합한 단순하고 덜 일반적인 유형의 생성자를 제공합니다. MPI_Type_create_struct
기본 유형(예: int 및 float)이 다른 경우에만 필요합니다.
예를 들어, 몇 가지 더 나은 솔루션이 있습니다.
두 정수가 연속적인 메모리 영역(예: 정수 배열)에 정렬되어 있다고 가정하면 파생 데이터 유형이 전혀 필요하지 않습니다.두 가지 유형의 요소만 전송/수신
MPI_INT
유형의 변수의 주소가 있는.car
송신/수신 버퍼로 사용:MPI_Send(&send, 2, MPI_INT, dest, tag, MPI_COMM_WORLD); MPI_Recv(&recv, 2, MPI_INT, src, tag, MPI_COMM_WORLD, &status);
파생 데이터 유형(예: 가독성 또는 재미를 위해)을 사용하려면 다음을 사용할 수 있습니다.
MPI_Type_contiguous
이는 배열에 해당합니다.MPI_Type_contiguous(2, MPI_INT, &mpi_car_type);
두 정수가 서로 다르게 정렬되어 있는 경우(대부분은 그렇지 않지만 기계에 의존하고 있으며 MPI 구현은 다양한 플랫폼에 대해 존재합니다),
MPI_Type_indexed_block
그것은 일련의 변위를 필요로 합니다 (예:MPI_Type_create_struct
)이지만 이전 형식의 인수는 하나뿐이며 각 블록의 블록 길이는 정의에 따라 1입니다.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);
다른 솔루션은 의미론적으로 올바르지만 읽기가 훨씬 어렵고 성능 저하가 클 수 있습니다.
를 .MPI_Type_create_struct
개체에 대한 사용자 지정 MPI 데이터 유형을 만듭니다.예를 들어 http://beige.ucs.indiana.edu/I590/node100.html 을 참조하십시오.
int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
는 OpenMPI를 합니다.count * sizeof(datatype)
음으로 시연바이트로 buf
int 배열과 같은 것을 보낼 수 있습니다.들어 array 를들배 10 int 을선는하경우언을 int arr[10]
와 함께 보낼 수 있습니다.
MPI_Send(arr, 10, MPI_INT, 1, 0, MPI_COMM_WORLD);
그리고 비슷하게 받습니다. 때부터buf
입니다. 이를 하여 보드포입다를 전송하여 할 수 있습니다. 우리는 이것을 사용하여 구조물을 보낼 수 있습니다.sizeof(my_struct)
바이트 및 수신측 구조체로 캐스팅합니다.다음은 예입니다.
#include "mpi.h"
#include <stdio.h>
typedef struct
{
char a;
int b;
short c;
} my_struct;
int main (int argc, char *argv[])
{
int numtasks, taskid;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
if (taskid == 0)
{
my_struct m;
m.a = '!';
m.b = 1234;
m.c = 5678;
MPI_Send(&m, sizeof(my_struct), MPI_CHAR, 1, 0, MPI_COMM_WORLD);
}
else
{
my_struct m;
MPI_Recv(&m, sizeof(my_struct), MPI_CHAR, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("%c %d %d\n", m.a, m.b, m.c);
}
MPI_Finalize();
}
C 배열은 데이터를 연속적으로 저장하기 때문에 구조 배열을 mallocation하는 방법과 유사한 구조 배열을 보낼 수도 있습니다.그래서 만약에 당신이my_struct m_array[10]
당신은 (그리고 비슷하게) 보낼 것입니다.
MPI_Send(m_array, sizeof(my_struct) * 10, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
언급URL : https://stackoverflow.com/questions/9864510/struct-serialization-in-c-and-transfer-over-mpi
'programing' 카테고리의 다른 글
eclipse 및 m2e와 함께 maven-jaxb-plugin을 사용할 때 ErrorListener가 누락됨 (0) | 2023.07.13 |
---|---|
Oracle 및 트리거(삽입, 업데이트, 삭제) (0) | 2023.07.13 |
11g의 select 문에서 새로 생성된 테이블 열에 대한 기본값을 설정하는 방법 (0) | 2023.07.08 |
VBA에서 현재 디렉터리를 경로로 지정하는 방법은 무엇입니까? (0) | 2023.07.08 |
SSMS .rpt 출력 파일을 .txt/.csv로 변환 (0) | 2023.07.08 |