How to use AutoLink in your source files ?
This is related to the use of AutoMap and AutoLink v2.20
The following file will explain how to use AutoMap generated files for AutoLink, and how to generate those files.
Warning : AutoLink requires AutoMap to generate some of its file, you can get both (or use the web version of AutoMap) from the MPI data-type tools home page.
Table of Contents
1) Create output files
1.1) Preparing structure file
1.1.1) Rules
1.1.2) Example
1.2) Running AutoMap
1.2.1) Concept
1.2.2) Example
2) Use of Output files in user code
2.1) Makefile definition
2.2) Edit user code
2.2.1) Concept
2.2.2) Example
2.3) Use of AutoLink functions
2.3.1) AL_Init(size)
2.3.1.1) Concept
2.3.1.2) Example
2.3.2) AL_SetPacketSize(size)
2.3.2.1) Concept
2.3.2.2) Example
2.3.3) AL_Send(buf, datatype, dest, tag, comm)
2.3.3.1) Concept
2.3.3.2) Example
2.3.4) AL_Recv(buf, datatype, source, tag, comm, status, reqlist)
2.3.4.1) Concept
2.3.4.2) Example 1
2.3.4.3) Example 2
2.3.5) AL_Finalize()
2.3.5.1) Concept
2.3.5.2) Example
2.3.6) AL_LogEntry(entry)
2.3.6.1) Concept
2.3.6.2) Example
2.3.7) AL_Free(reqlist)
2.3.6.2) Example
2.4) Running code
3) Troubleshooting
To prepare the structure file to be processed by AutoMap, a few rules are to be explained :
- a begin mark
/*~ AM_Begin */ must be placed before the type definitions.
- an end mark
/*~ AM_End */ must be inserted after the type definitions.
- each type that the user want to recognize must have
/*~ AM */ after the typedef declaration, and before the last semi-colon (;) of the line.
- each type referred to by pointer does not have to be AutoMap marked for AutoLink to process completely. If type A uses a pointer reference to type B, but user only want to have control other type A, it is not necessary to AutoMap mark type B.
- each pointer type must be strongly typed; no
void * can be used for AutoLink.
- no types such as
char * can be used in data-types, but char element[size] can (and must) be used instead.
- Warning : AutoMap does not work with
struct alone (using an AutoMap marker), all types must be used as typedef struct.
The following lines are a very simple example of a possible use of AutoMap to generate AutoMap (MPI data-types) and AutoLink (traversing and recreation of dynamic data-types) output files.
Let's call the following file for future references struct.h
/*~ AM_Begin */
typedef struct {
int a;
char b;
int c;
} intStruct;
struct _Partstruct {
intStruct* test;
int class;
double d[6];
char b[7];
int c[8];
};
typedef struct _Partstruct Partstruct /*~ AM */;
/*~ AM_End */
1.2.1) Concept
You must run AutoMap in the directory where you want the output files to be generated.
To run AutoMap, if it is in your path, simply type the name or your AutoMap executable, otherwise put the full pathname to it, and the name of the executable.
AutoMap options are :
AutoMap [-help | [-v] [-noAL] [-log] filename]
-help : Will print this help menu
-v : Verbose mode
-noAL : Will not generate the entries for use with AutoLink
-log : Will generate the "logbook.txt" for this run
filename : name of the C typedef definition file to analyze
When using AutoMap, you may want to have a look at the log file (logbook.txt) that AutoMap generates when asked to (-log option); but this is for users who want to understand to the lowest level how AutoMap works. For other users, should they want to follow the processing of AutoMap, it is easy to run it in "verbose" (-v option) mode, so that you can see if all the data-types you expected are generated.
In the case where you do not want to use AutoLink --for example cases where you do not have pointers to follow, but only basic data-types-- use the "no AutoLink" (-noAL) option.
The filename is the name of the file containing the data-types to be AutoMap created, formatted as defined in section 1.1.
We run AutoMap on the file "struct.h" defined previously, in verbose mode :
AutoMap -v -log struct.h
, gives us :
Identification : AutoMap 2.20
Information on this run :
- Will generate AutoLink output files
- Will process file : struct.h
Creating AutoMap log file ... done
Creating the AST ... done
Updating the AST ... done
Writing mpitypes.inc (& mpitypes.h) ... done
Writing al_routines.inc (& autolink.h) ... done
--> Generated output for :
----> intStruct (AutoMap and AutoLink subType)
----> Partstruct (userType)
--> done
Cleaning the AST ... done
Closing log file ... done
AutoMap finished without error
Output files can be found in current directory.
AutoMap remarks can be found in the logbook file.
0 Errors, 0 Warnings, Highest Severity 0
, telling us that output for data-types intStruct and Partstruct have been generated, both for their MPI type creation and AutoLink.
The file generated are :
-
autolink.h : to specify the prototype of the functions available to the user.
-
al_routines.inc : to specify internal definitions to AutoLink send and receive functions.
-
mpitypes.inc : contains the function required to create the MPI data-types.
-
mpitypes.h : to define functions and types prototypes.
-
logbook.txt : to store the generation log (only generated because of the -log option).
With AutoLink should come a base Makefile that should help you create run use AutoMap and AutoLink, should you just take the time to adapt the Makefile to your needs.
2.2.1) Concept
To have AutoLink ready, you should have the following files :
-
al_common.h
-
al_internals.c
-
al_internals.h
-
al_routines.inc
-
autolink.h
-
autolink.inc
-
mpitypes.inc
-
mpitypes.h
, also the user code (here called userprog.c) and the type definition file (here struct.h).
The following pictures explains mostly the use of those files :
To be able to use AutoLink, should your type definition file be struct.h, in your main code, please, include in the following order the following files :
-
mpi.h
-
struct.h
-
autolink.inc
In any deported code that should use AutoLink, include in the following order (* means that it is not always required)
-
mpi.h (*)
-
struct.h (*)
-
autolink.h
If the main code definition is done in userprog.c:
#include <mpi.h>
#include "struct.h"
#include "autolink.inc"
, will make AutoLink functions available to user code.
2.3) Use of AutoLink functions
Use AL_Init only in the main definition and after having done MPI_Init
The size parameter is an integer value given in bytes, setting the PacketSize. Note that a negative value will make AutoLink use the default PacketSize set in al_common.h
In file userprog.c :
main(int argc,char* argv[])
{ /* main */
MPI_Init(&argc,&argv);
AL_Init(8000); /* Let's use a 8000 bytes PacketSize */
Will enable the user to change the maximum size of the packet sent for each data-type, by setting the new size to size bytes. This need to be done for each AutoLink communicating processes.
Note that since AutoLink v2.20, the user should only set PacketSize during AL_Init. If is forbidden --due to the new internal block data-type-- to dynamically change it. The only case when this is allowed is if the user acknowledge taking full care of possible memory leaks that may be introduced. To enable it, a define (AL_USERCONTROL_PACKET) has to be set.
Mostly, it is recommanded to only use PacketSize control for PacketSize Tuning (see source included example).
AL_SetPacketSize return an integer (AL_True or AL_False) to confirm the changes done.
In file userprog.c, after having done the AutoLink initialization :
if (AL_SetPacketSize(8192) == AL_True) {
/* Note that if not allowed, an entry will be added to the log (if allowed) */
Will transfer a dynamic data-type following every --first level-- pointer in the data-type from entry point buf of data-type datatype (defined by AL_ + data-type name) to MPI rank dest with matching tag and communicator. Return MPI_SUCCESS if no error encountered.
In file userprog.c, should it be an MPI program of rank 2, if sending is done on rank 0, and var being a filled data-type of type Partstruct * :
[...]
Partstruct *var;
[... filling var]
tag = 0;
next_rank = 1;
if (AL_Send(var, AL_Partstruct, next_rank, tag, MPI_COMM_WORLD)
!= MPI_SUCCESS) { /* if */
printf("Error in Sending");
exit(1);
}
Will receive and reconstruct a data-type sent by AutoLink through the command AL_Send. Will store the address of the first element of the recreated dynamic data-type into buf (need the address of a pointer), and the data-type of the recreated element in datatype (need the address of a integer variable). This for an element sent from source with matching tag and comm. Plus if given, will store an MPI status into status.
Since AutoLink v2.20, a new parameter can be given; reqlist. This parameter can be :
-
NULL : in this case, AutoLink will behave like the old version; recreating each element in memory so that users can free them.
-
AL_ReqList ** : by using this additional argument, users provide a pointer (to a pointer) of AL_ReqList (AutoLink will take care of memory allocation and freeing) so that every AutoLink's special memory block used is recorded. Data-types elements can then no more be freed individually, but all can be freed using a new function : AL_Free
(Each element is created in memory)
In file userprog.c, should it be an MPI program of rank 2, if receiving is done on rank 1, and var being a data-type of type Partstruct * (not filled, neither malloced).
Partstruct *var;
MPI_Status status;
next_rank = 0;
tag = 0;
if (AL_Recv((void *) &var, &tmp, next_rank, tag, MPI_COMM_WORLD, &status, NULL)
!= MPI_SUCCESS) {/* if */
printf("Error in Receiving");
exit(1);
}
[...]
/* User freeing "var" using free on each element of the entire data-type */
(Same example using AL_ReqList)
Partstruct *var;
AL_ReqList *varALfree;
MPI_Status status;
next_rank = 0;
tag = 0;
if (AL_Recv((void *) &var, &tmp, next_rank, tag, MPI_COMM_WORLD, &status, &varALfree)
!= MPI_SUCCESS) {/* if */
printf("Error in Receiving");
exit(1);
}
[...]
/* Empty var : AL_Recv'd */
AL_Free(&varALfree);
Finalizing AutoLink is to be done before MPI_Finalize.
In userprog.c ;
AL_Finalize();
MPI_Finalize();
Add a user entry to the AutoLink "benchmark log". Requires the _AL_DBG_UBENCH define to add entries. AutoLink extractor script (al_bench.pl) will get the time and packet size before the user data. It is an easy way for the user to generate additional entries for special benchmarking by formatting the printed entries.
In userprog.c ;
#include <string.h>
[...]
char stmp[80];
[...]
sprintf(stmp, "%d \t%f # %s\n",iteration, value, comment);
AL_LogEntry(stmp);
, will add in the log an entry with the iteration number, the value followed by a # and a comment text. Such an example can be used in a data visualization tool like "gnuplot", giving a third and fourth column to work with and a comment on which the user can always "grep" in order to extract special data.
This function is here to delete every element created by AutoLink using AL_Recv and specifying a reqlist.
See AL_Recv for an example of use.
After compiling code (see the basic Makefile given), you should be able to try it and enjoy the high level functions provided by AutoLink to you.
3) Troubleshooting
Please check the following :
- You did not forget the begin (
/*~ AM_Begin */) and end (/*~ AM_End */) marker, before and after the type definitions.
- You did use the AutoMap type marker (
/*~ AM */) on the type you desire to work with.
- You did not use the AutoMap type marker on a struct alone.
- You used the proper options when launching AutoMap
- You included the proper file.
- You used AutoLink functions, as defined in the examples.
Should you encounter another problem, please, set a trace mode for AutoMap creation and/or AutoLink. Add to it your type definition file, command lines, and a small example of how you use AutoMap and AutoLink to martial.michel@nist.gov with [ALpb] in the subject.
Martial Michel
Last modified: Tue Jun 22 17:38:55 EDT 1999