# Derived datatypes (MPI) MPI's built-in types (`MPI_INT`, `MPI_DOUBLE`, etc.) describe contiguous arrays of a single type. When the data you want to send is scattered in memory — a column of a row-major matrix, alternating elements, fields from a struct — you have two options. The first is to copy the elements manually into a flat temporary buffer: ```c double tmp[N_ROWS]; for (int i = 0; i < N_ROWS; i++) tmp[i] = matrix[i][col]; MPI_Send(tmp, N_ROWS, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD); ``` This adds an allocation and a copy on every send. Derived datatypes describe the layout of the original data so MPI can gather it directly without an intermediate buffer. `MPI_Type_vector` describes a strided pattern: `count` blocks of `blocklength` elements separated by a `stride`. ```c MPI_Datatype col_t; // one column of a row-major matrix: N_ROWS blocks of 1 double, stride = N_COLS MPI_Type_vector(N_ROWS, 1, N_COLS, MPI_DOUBLE, &col_t); MPI_Type_commit(&col_t); MPI_Send(&matrix[0][col], 1, col_t, dest, 0, MPI_COMM_WORLD); MPI_Type_free(&col_t); ``` `MPI_Type_create_struct` describes a struct with mixed types, matching a C struct layout. Every derived type must be committed with `MPI_Type_commit` before use and freed with `MPI_Type_free` when done.