Skip main navigation

Layout of struct data types

So far we learnt how to transfer continuous vectors. How would we transfer if there are some gaps or holes in the vectors?

Vector data types

What we learnt so far in the previous subsection and the exercise were more like continuous vectors. Sometimes we would need to communicate vectors with holes that we do not want to be transferred. This implies that we would not send each element but just selected elements or sequence of elements. Therefore the block length and the offset of each can be used to create a stride. When we want to communicate just a portion of a continuous chunk of memory the destination and source may not be the same. Usually, we have one element to receive the results back from the array of cluster. We saw in the previous Pi example how the integrals were collected back, so that we see the complete sums for which we could use such vector data types.

Vector Image courtesy: Rolf Rabenseifner (HLRS)

We use the following routine for vector data types:

int MPI_Type_vector (int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype)

The structure of the routine is similar to most we have learnt previously:

  • count suggests how many elements
  • blocklength is the number of elements per block
  • stride is the offset to the next portion of the result
  • Datatype – we can have only one data type here and it could be a derived one. Of course, we can communicate a strided array of slots and integers and subsequently we will get a newtype created that can be used in send and receive routines.

Struct data type

So, we could have old types that are of different sizes and then we could combine two old types into a single vector or a block that can be also with holes and these holes will not be communicated. This is a more prevalent way to describe the type instead of doing what we saw earlier. The previous method is not optimal for large numbers of such kinds of arrays. In such cases we use the struct data types, so that communication is executed in the correct way.

The routine for this data type looks like

int MPI_Type_create_struct (int count, int *array_of_blocklengths, MPI_Aint *array_of_displacements, MPI_Datatype *array

This is how memory layout of struct data types could look like with gaps inside that we don’t actually want, but are imposed by the compiler itself or the underlying operating system or hardware processor.

Memory layout of struct datatypes

Let’s assume that we have the following parameters:

count = 2
array_of_blocklengths = ( 3, 5 )
array_of_displacements = ( 0, addr_1 – addr_0 )
array_of_types = ( MPI_INT, MPI_DOUBLE )

In this case the prototype for fixed memory layout of the struct data type would be as follows:

struct buff {
int i_val[3];
double d_val[5];
}
This article is from the free online

Introduction to Parallel Programming

Created by
FutureLearn - Learning For Life

Our purpose is to transform access to education.

We offer a diverse selection of courses from leading universities and cultural institutions from around the world. These are delivered one step at a time, and are accessible on mobile, tablet and desktop, so you can fit learning around your life.

We believe learning should be an enjoyable, social experience, so our courses offer the opportunity to discuss what you’re learning with others as you go, helping you make fresh discoveries and form new ideas.
You can unlock new opportunities with unlimited access to hundreds of online short courses for a year by subscribing to our Unlimited package. Build your knowledge with top universities and organisations.

Learn more about how FutureLearn is transforming access to education