C-DVM compiler |
Contents
2
The sequence of compilation
3 Compilation of C-DVM constructs
3.1.1 DISTRIBUTE directive
3.1.2 GENBLOCK distribution format
3.1.3 ONTO clause
3.1.4 REDISTRIBUTE directive
3.1.5 ALIGN directive
3.1.6 REALIGN directive
3.1.7 TEMPLATE clause
3.1.8 CREATE_TEMPLATE directive
3.2.1 PARALLEL directive
3.2.2 ACROSS clause
3.2.3 PROCESSORS directive and NUMBER_OF_PROCESSORS() function
3.2.4 TASK directive
3.2.5 MAP directive
3.2.6 TASK_REGION directive
3.2.7 ON-block construction
3.2.8 ON-loop construction
3.3.1 SHADOW clause
3.3.2 SHADOW_RENEW clause
3.3.3 SHADOW_GROUP directive
3.3.4 CREATE_SHADOW_GROUP directive
3.3.5 SHADOW_START directive
3.3.6 SHADOW_START clause
3.3.7 SHADOW_WAIT directive
3.3.8 SHADOW_WAIT clause
3.4.1 REMOTE_ACCESS directive and clause
3.4.2 REMOTE_GROUP directive
3.4.3 PREFETCH directive
3.4.4 RESET directive
3.4.5 Remote references
3.5.1 REDUCTION_GROUP directive
3.5.2 REDUCTION clause
3.5.3 Reduction variables and operations
3.5.4 REDUCTION_START directive
3.5.5 REDUCTION_WAIT directive
3.6.1 Creation and deletion of distributed arrays
3.6.2 Static distributed arrays
3.6.3 References to distributed data
3.6.4 Own computation
3.6.5 Initializing and finalizing of program execution
3.6.6 Input-output functions
3.7.1 Performance analyzer. Loops
3.7.2 Performance analyzer. INTERVAL directive
3.7.3 Debugger. Data tracing
3.7.4 Debugger. Computation tracing
3.7.5 Sequential code
C-DVM is the C language extended by special annotations for specifying parallel execution of a program. These annotations are called DVM-directives. C-DVM compiler translates an annotated C-DVM program to a SPMD stile program that contains calls to run-time library (RTL).
Besides "pure" parallel code the compiler should be able to produce an "extended" debugging code to use features of the performance analyzer and debugger, and also a "sequential" code (i.e. without RTL calls) with such debugging extensions.
Compiler should recognize the following four types of constructs and perform corresponding actions and code transformations:
For the Performance Analyzer the Compiler should process:
All of these are implemented as invocations of corresponding functions of the analyzer.
For the Debugger the Compiler should provide:
All of these are implemented as invocation of corresponding functions of the debugger. A point of registration of initialized variables is determined by the compiler.
Sequential execution mode is required to obtain performance characteristics of source program and so called "reference" trace to debug in trace comparison mode. All DVM-directives are ignored except for the following:
Program compilation is accomplished in the following steps.
For convenience and flexibility output code is written without direct use of RTL functions. Output code contains macros providing all necessary information at a given point of output program, hiding low-level details of RTL library interface. The final generation is performed by the C preprocessor using macrodefinitions of C-DVM macros (File cdvm_c.h.)
3 Compilation of C-DVM constructs
Necessity of program transformation for parallel execution is caused by distribution of data and computations.
Distribution of data consists in splitting of arrays into parts and placing such parts to local memories of different processors. On each processor RTL defines size of local part (considering shadow edges) and allocates memory for it. For program this local part is accessible through array handler. So original sequential statements for allocating and accessing distributed data should be found in source code and replaced.
Distribution of computation consists in splitting of the whole index space of a loop to parts and execution on different processors of different set of loop iterations. In every processor local part of parallel loop is described by a loop handler. So sequential loop headers should be replaced.
In this section all transformations of C-DVM program performed by the compiler are described.
Context and syntax.
DVM( ["*"] DISTRIBUTE [ format...] [ ONTO target ] [ ; SHADOW-clause ] [ ; TEMPLATE-clause ] ) C-declaration ;
Proposed compiler output.
long array-id [ rank+1 ];
Note. Source declaration is substituted. All other information from the declaration and directive will be used later in other constructions generating and distributed data references recognizing.
3.1.2 GENBLOCK distribution format
Context and syntax.
DVM(DISTRIBUTE ... "[" GENBLOCK( int-array ) "]"... ) DVM(REDISTRIBUTE ... "[" GENBLOCK( int-array ) "]"... )
Proposed compiler output.
DVM_GENBLOCK(am,ps,k,gbs);
Note. The macro is generated not at the point of DISTRIBUTE directive, but in a sequence of (explicit or implicit) array creation. Macro DVM_GENBLOCK(am,ps,k,gbs) is expanded to
DVM_AM=am? am : getam_(); DVM_PS=ps? ps : getps_(NULL); genbli_(&DVM_PS, &DVM_AM, (AddrType*) gbs, k);
Context and syntax.
DVM(DISTRIBUTE ... ONTO target ... )
Proposed compiler output.
DVM_ONTO(ps,k,ls,hs)
Note. The macro is generated not at the point of DISTRIBUTE directive, but in a sequence of (explicit or implicit) array creation. It creates a processors subsystem which will be used instead of the current one (default). Macro DVM_ONTO(ps,k,ls,hs) is expanded to
DVM_PS=ps; DVM_PS=crtps_(&DVM_PS, ls, hs, DVM_0000);
Context and syntax.
DVM(REDISTRIBUTE array format... [ NEW ] ) ;
Proposed compiler output.
DVM_REDISTRIBUTE(amv,ps,k,axs,new);
Note. The executable directive is converted to a statement. Macro DVM_REDISTRIBUTE(amv,ps,k,axs,new) is expanded to
{DVM_PS=ps; redis_((AMViewRef*) amv, &DVM_PS, k, axs, 0, new); }
Context and syntax.
DVM(["*"] ALIGN [ "["dummy-var"]"... ] WITH base "["align-expr"]"... [ ; SHADOW-clause ] ) C-declaration ;
Proposed compiler output.
long array-id [ rank+1 ];
Note. Source declaration is substituted. All the other information from the declaration and directive should be used later in generating other constructions and recognizing of references to distributed data.
Context and syntax.
DVM( REALIGN array "["dummy-var"]"... WITH base "["align-expr"]"... ) ;
Proposed compiler output.
DVM_REALIGN(arr,base,k,i,a,b,new);
Note. The executable directive is converted to a statement. Macro DVM_REALIGN(arr,base,k,i,a,b,new) is expanded to
{realn_(arr, (PatternRef*)(base), i, a, b, new); }
Context and syntax.
DVM(DISTRIBUTE ... ; TEMPLATE [ "["size"]"... ] ) void * template-id ;
Proposed compiler output.
AMViewRef template-id;
Note. Source declaration is substituted. Distribution formats will be used in creation of the template. If sizes present creation will be implicit.
3.1.8 CREATE_TEMPLATE directive
Context and syntax.
DVM(CREATE_TEMPLATE template-id "["size"]"... ) ;
Proposed compiler output.
DVM_CREATE_TEMPLATE(am,t,r,di); DVM_DISTRIBUTE(amv,ps,k,axs);
Note. The executable directive is converted to a statement. Macro DVM_CREATE_TEMPLATE(am,t,r,di) is expanded to
{if(am==0) DVM_AM=getam_(); else DVM_AM=am; t=crtamv_( (AMRef*)DVM_AM, r, di, 0); }
Macro DVM_DISTRIBUTE(amv,ps,k,axs) is expanded to
{DVM_PS=ps; DVM_AMV=amv; distr_( &DVM_AMV, &DVM_PS, k, axs, 0); }
These macros are also generated to create and distribute an implicit template for any distributed (not aligned) array.
3.2 Distribution of computations (loops and tasks)
Context and syntax.
DVM ( PARALLEL "["loop-var"]"... ON base "["align_expr"]"... [ ; sub-directives]... ) loop-nest
Proposed compiler output.
{ [ dvm_create_rg ] DVM_PARALLEL(n,r); [ other sub-directives... ] DVM_DO_ON((n,r,vs,ls,hs,ss,base,rb,is,as,bs); [ dvm_reduction or dvm_reduction20 ] { DVM_DOPL(n) loop-headers DVM_FOR... { loop-body } } [ end_reduction ] DVM_END_PARALLEL(n); }
Note. Macro DVM_PARALLEL(n,r) is expanded to
{long DVM_LO##n[r], DVM_HI##n[r], DVM_ST##n[r]; LoopRef DVM_LP##n; DVM_LP##n=crtpl_(DVM_A0(r))
Macro Macro DVM_DO_ON(n,r,vs,ls,hs,ss,base,rb,is,as,bs) is expanded to
mappl_(&DVM_LP##n, (PatternRef*)(base), is, as, bs, vs, 1, ls, hs, ss, DVM_LO##n, DVM_HI##n, DVM_ST##n);
Macro DVM_DOPL(n) is expanded to
while(dopl_(&DVM_LP##n))
Macro DVM_FOR(n,v,k,lh) is expanded to
for(v=DVM_LO##n[k]; v<=DVM_HI##n[k]; v+=DVM_ST##n[k])
Macro DVM_REDBLACK(n,v,k,e,lh) is expanded to
for(v=DVM_LO##n[k]+(DVM_LO##n[k]+e)%2;v<=DVM_HI##n[k];v+=2)
Macro DVM_END_PARALLEL(n) is expanded to
endpl_(&DVM_LP##n);}
Context and syntax.
DVM ( PARALLEL ... ; ACROSS array "["widths"]"... )
Proposed compiler output.
dvm_parallel ... sub_directives DVM_ACROSS(loopid, ( DVM_ACROSS_SH(a,k,ls,hs,corner) // for each renewee ... )) { dvm_dopl loop-headers... loop-body } DVM_END_ACROSS() [ end_reduction ] dvm_end_parallel
Note. Macro DVM_ACROSS(loopid,shads) is expanded to
{ShadowGroupRef DVM_LSG; ShadowGroupRef DVM_HSG; int DVM_LorH; DVM_LSG=crtshg_(0); DVM_HSG=crtshg_(0); DVM_LorH=1; shads; strtsh_(&DVM_HSG); waitsh_(&DVM_HSG); delshg_(&DVM_HSG); DVM_LorH=0; shads; recvsh_(&DVM_LSG); waitsh_(&DVM_LSG);
Macro DVM_END_ACROSS() is expanded to
sendsh_(&DVM_LSG); waitsh_(&DVM_LSG); delshg_(&DVM_LSG); }
Macro DVM_ACROSS_SH(a,k,ls,hs,corner) is expanded to
((DVM_LorH ? inssh_(&DVM_HSG, a, 0, hs, corner) :inssh_(&DVM_LSG, a, ls, 0, corner) ), )
3.2.3 PROCESSORS directive and NUMBER_OF_PROCESSORS() function
Context and syntax.
DVM(PROCESSORS "["dim"]"...) void * proc_id ;
Proposed compiler output.
PSRef proc_id; ... DVM_PROCESSORS(Iproc_id),r,dims);
Note. Source declaration is substituted. The macro is generated not at the point of declaration, but in a sequence of implicit actions. Macro DVM_PROCESSORS(proc,r,dims) is expanded to
{DVM_PS=getps_(NULL); proc=psview_(&DVM_PS, r, dims, 0); }
Macro NUMBER_OF_PROCESSORS() is expanded to
(DVM_PS=getps_(NULL), getsiz_((ObjectRef*)&DVM_PS,0))
Context and syntax.
DVM(TASK) void * task-id "["size"]"
Proposed compiler output.
AMViewRef AMV_task-id; PSRef task-id [ size ]={0}; ... DVM_TASK(task-id,n);
Note. Source declaration is substituted. The macro is generated not at the point of declaration, but in a sequence of implicit actions. Macro DVM_TASK(id,n) is expanded to
AMV_##id=crtamv_(getam_(), 1, n, 0);
Context and syntax.
DVM(MAP task-id"["task_ind"]" ONTO proc-section );
Proposed compiler output.
DVM_MAP(task,ind, [ DVM_ONTO(ps,k,ls,hs) ]) ;
Note. The executable directive is converted to a statement. Macro DVM_MAP(task,ind,ps) is expanded to
ps; task[ind]=DVM_PS; mapam_(getamr_(&AMV_##task,ind), &DVM_PS);
Context and syntax.
DVM(TASK_REGION task-id) { ON-block... | ON-loop }
Proposed compiler output.
{DVM_TASKREGION(no,task); ... }
Note. Macro DVM_TASKREGION(no,task) is expanded to
AMViewRef AMV_0; AMViewRef DVM_LP##no=AMV_##task;
Context and syntax.
DVM(ON task-id "["task-ind"]") { C-statements }
Proposed compiler output.
if(DVM_RUN(task,ind)) { statements DVM_STOP(); }
Note. Macro DVM_RUN(task,ind) is expanded to
runam_(getamr_(&AMV_##task,ind))
Macro DVM_STOP() is expanded to
stopam_()
Context and syntax.
DVM(PARALLEL "["var"]" ON task-id "["var"]") DO(var, ..., ..., ...) { C-statements }
Proposed compiler output.
for(var=0; ...) if(DVM_RUN(task,var)) { statements DVM_STOP(); }
Context and syntax.
DVM( DISTRIBUTE | ALIGN ... ; SHADOW "["widths"]"... )
Note. Nothing is generated at this point. Compiler keeps provided widths as the maximal width of shadow edges. They will be used for array creation.
Context and syntax.
DVM(PARALLEL ... ; SHADOW_RENEW renewee... ... ) renewee ::= array [ "["widhs"]"... ] [ CORNER ]
Proposed compiler output.
DVM_SHADOW_RENEW(loop-number, (DVM_SHADOWS(a,k,ls,hs,corner), // for each renewee ... ))
Note. It is shorthand for the sequence "CREATE_SHADOW_GROUP; SHADOW_START; SHADOW_WAIT;" with temporary shadow group, performed before the loop. Macro DVM_SHADOW_RENEW(n,das) is expanded to
{ShadowGroupRef DVM_SG=crtshg_(0); das; strtsh_(&DVM_SG); waitsh_(&DVM_SG); delshg_(&DVM_SG); }
Macro DVM_SHADOWS(a,k,ls,hs,corner) is expanded to
inssh_(&DVM_SG, a, ls, hs, corner)
Context and syntax.
DVM(SHADOW_GROUP) void * sh-group-id;
Proposed compiler output.
ShadowGroupRef sh-group-id;
Note. Source declaration is substituted.
3.3.4 CREATE_SHADOW_GROUP directive
Context and syntax.
DVM(CREATE_SHADOW_GROUP sh-group-id : renewee... );
Proposed compiler output.
DVM_CREATE_SHADOW_GROUP( sh-group-id, (DVM_SHADOWS(a,k,ls,hs,corner), // for each renewee ... ))
Note. The executable directive is converted to a statement. Macro DVM_CREATE_SHADOW_GROUP(sg,shads) is expanded to
{ShadowGroupRef DVM_SG; if(sg!=0) delshg_(&sg); DVM_SG=crtshg_(0); shads; sg=DVM_SG; }
Context and syntax.
DVM(SHADOW_START sh-group-id);
Proposed compiler output.
DVM_SHADOW_START(sg);
Note. The executable directive is converted to a statement. Macro DVM_SHADOW_START(sg) is expanded to
strtsh_(&sg)
Context and syntax.
DVM(PARALLEL ... ; SHADOW_START sh-group-id ... ) ...
Proposed compiler output.
DVM_PAR_SHADOW_START(n,sg); // in loop header
Note. Macro DVM_PAR_SHADOW_START(n,sg) is expanded to
exfrst_(&DVM_LP##n,&sg)
Context and syntax.
DVM(SHADOW_WAIT sh-group-id);
Proposed compiler output.
DVM_SHADOW_WAIT(sg);
Note. The executable directive is converted to a statement. Macro DVM_SHADOW_WAIT(sg) is expanded to
waitsh_(&sg)
Context and syntax.
DVM(PARALLEL ... ; SHADOW_WAIT sh-group-id ...) ...
Proposed compiler output.
DVM_PAR_SHADOW_WAIT(n,sg); // in loop header
Note. Macro DVM_PAR_SHADOW_WAIT(n,sg) is expanded to
imlast_(&DVM_LP##n,&sg)
3.4.1 REMOTE_ACCESS directive and clause
Context and syntax.
DVM(REMOTE_ACCESS ra-reference...) C-statement DVM(PARALLEL ... ; REMOTE_ACCESS [ ra-group : ] ra-reference... ...) ... ra-reference ::= array [ "["[expr]"]"... ]
Proposed compiler output.
DVM_BLOCK_BEG(); DVM_REMOTE20(arr,buf,k,as,bs); statements using remote references DVM_BLOCK_END();
Note. Macro DVM_REMOTE20(arr,buf,k,as,bs) is expanded to
{static long buf[2*k+2]; crtrbl_(arr, buf, NULL, 0, NULL, 1, as, bs); loadrb_(buf, 1); waitrb_(buf);}
Macro DVM_REMOTE20G(n,rg,arr,buf,k,is,as,bs) is expanded to
if(RMG_##rg==1) {waitbg_(&rg); RMG_##rg=2;} if(RMG_##rg==0) {crtrbl_(arr, buf, NULL, 1, &DVM_LP##n, is, as, bs); loadrb_(buf, 1); waitrb_(buf); if(rg==0) {rg=crtbg_(1, 1);} insrb_(&rg, buf); }
Context and syntax.
DVM(REMOTE_GROUP) void * ra-group-id;
Proposed compiler output.
RegularAccessGroupRef ra-group-id; long RMG_ra-group-id;
Note. Source declaration is substituted. The PREFETCH and RESET operations require a flag variable to control buffer update operations.
Context and syntax.
DVM(PREFETCH ra-group-id );
Proposed compiler output.
DVM_PREFETCH(rg);
Note. The executable directive is converted to a statement. Macro DVM_PREFETCH(rg) is expanded to
if(rg==0) {RMG_##rg=0;} else {loadbg_(&rg, 1); RMG_##rg=1; }
Context and syntax.
DVM(RESET ra-group-id );
Proposed compiler output.
DVM_RESET(rg);
Note. The executable directive is converted to a statement. Macro DVM_RESET(rg) is expanded to
delbg_(&rg); rg=0; RMG_##rg=0;
Remote references are substituted by references to remote buffers.
3.5.1 REDUCTION_GROUP directive
Context and syntax.
DVM(REDUCTION_GROUP) void * red-group-id;
Proposed compiler output.
RedGroupRef red-group-id;
Note. Source declaration is substituted.
Context and syntax.
DVM( PARALLEL | TASK_REGION ... ; REDUCTION [ red-group-id : ] red-operation... ... ) ...
Proposed compiler output.
DVM_CREATE_RG(rg, ( DVM_RVAL(...) | DVM_RLOC(...) // for each operation ... )); loop creation and mapping DVM_REDUCTION20(loopid,rg); // insert to the group loop headers and body [ DVM_END_REDUCTION(); ] // synchronous reduction
Note. Macro DVM_CREATE_RG(rg,rvs) is expanded to
if(rg==0) rg=crtrg_(1,1); (void)rvs;
Macro DVM_REDUCTION(loopid,rvs) is expanded to
{ RedGroupRef DVM_RG; LoopRef DVM_LP0=0; PSSpaceRef DVM_PSSpace=DVM_LP##loopid; DVM_RG=crtrg_(1, 1); (void)rvs; DVM_INSERT_RV();
Macro DVM_REDUCTION20(loopid, rg) is expanded to
{ RedGroupRef DVM_RG=rg; LoopRef DVM_LP0=0; PSSpaceRef DVM_PSSpace=DVM_LP##loopid; DVM_INSERT_RV(); rg=DVM_RG;}
Macro DVM_INSERT_RV() is expanded to
while(CDVM_TOP!=CDVM_BOTTOM) { insred_( &DVM_RG, (RedRef*)CDVM_TOP, &DVM_PSSpace, 1); }
Macro DVM_END_REDUCTION() is expanded to
{strtrd_(&DVM_RG); waitrd_(&DVM_RG); delrg_(&DVM_RG);} }
3.5.3 Reduction variables and operations
Context and syntax.
DVM(...; REDUCTION ... MAX(red-var) ... ) DVM(...; REDUCTION ... MIN(red-var) ... ) DVM(...; REDUCTION ... SUM(red-var) ... ) DVM(...; REDUCTION ... PROD(red-var) ... ) DVM(...; REDUCTION ... AND(red-var) ... ) DVM(...; REDUCTION ... OR(red-var) ... ) DVM(...; REDUCTION ... MAXLOC(red-var,loc-var) ... ) DVM(...; REDUCTION ... MINLOC(red-var,loc-var) ... )
Proposed compiler output.
DVM_RVAR(rf_MAX,var,t,l) DVM_RVAR(rf_MIN,var,t,l) DVM_RVAR(rf_SUM,var,t,l) DVM_RVAR(rf_PROD,var,t,l) DVM_RVAR(rf_AND,var,t,l) DVM_RVAR(rf_OR,var,t,l) DVM_RLOC(rf_MAX,var,t,l,loc-var) DVM_RLOC(rf_MIN,var,t,l,loc-var)
Note. The parameter t is a code of type of variable (rt_INT, rt_LONG, rt_FLOAT, rt_DOUBLE). Parameter l is the number of elements in red-var (if it is an array) or 1. Macro DVM_RVAR(f,v,t,l) is expanded to
crtred_(f, &(v), t, l, 0, 0, 1)
Macro DVM_RLOC(f,v,t,l,loc) is expanded to
crtred_(f, &(v), t, l, &(loc), sizeof(loc), 1)
3.5.4 REDUCTION_START directive
Context and syntax.
DVM(REDUCTION_START red-group-id);
Proposed compiler output.
DVM_REDUCTION_START(red-group-id);
Note. The executable directive is converted to a statement. Macro DVM_REDUCTION_START(rg) is expanded to
strtrd_((RedGroupRef*) &rg)
3.5.5 REDUCTION_WAIT directive
Context and syntax.
DVM(REDUCTION_WAIT red-group-id);
Proposed compiler output.
DVM_REDUCTION_WAIT(red-group-id);
Note. The executable directive is converted to a statement. Macro DVM_REDUCTION_WAIT(rg) is expanded to
waitrd_((RedGroupRef*) &rg); delrg_((RedGroupRef*) &rg); rg=0;
3.6.1 Creation and deletion of distributed arrays
Context and syntax.
array = malloc(dim1 *...* dimr * elem-size); free( array );
Proposed compiler output. It includes all or part of the following statements depending on array declaration.
[ DVM_CREATE_TEMPLATE(am,t,r,di); // implicit template ] [ DVM_ONTO(ps,k,ls,hs); // target system ] [ DVM_DISTRIBUTE(amv,ps,k,axs); // distribute template ] [ DVM_GENBLOCK(am,ps,k,gbs); // GENBLOCK parameters ] DVM_MALLOC(arr,r,len,dim,lw,hw,redis) // initialize array handler [ DVM_ALIGN(arr,base,k,i,a,b) // align with template ]
Note. Macro Macro DVM_MALLOC(arr,r,len,dim,lw,hw,redis) is expanded to
{crtda_( arr, 0, NULL, r, len, dim, 0, redis, lw, hw ); }
Macro DVM_ALIGN(arr,base,k,i,a,b) is expanded to
{align_( arr, &(base), i, a, b); }
Macro DVM_FREE(arr) is expanded to
(delda_(arr));
3.6.2 Static distributed arrays
Context and syntax.
DVM(DISTRIBUTE | ALIGN...) element-type array-id "["const-dim"]"...;
Proposed compiler output. Standard array creation sequence as for malloc.
Note. For global declarations implicit malloc is inserted at the beginning of the main function. For local declarations it is inserted before the first statement of the block.
3.6.3 References to distributed data
Context and syntax. Ordinary references to array elements array[ind1]...[indr] with distributed array. Special form array(ind1,...,indr) is allowed for macro simulation of dynamic arrays.
Proposed compiler output.
DAElm<r>(type,array-id,ind1,...indr)
Note. These are macros of RTL.
Context and syntax.
lhs=rhs; // assignment
Proposed compiler output.
if(DVM_ISLOCAL(lhs)) { lhs = rhs ; } DVM_ENDLOCAL();
Note. Own computation statement is an assignement to a distributed array in a non distributed branch of program. It should be guarded by the test of locality. Macro DVM_ISLOCAL(a,r,ind) is expanded to
tstelm_(a, ind)
Macro DVM_ENDLOCAL() is expanded to
dskpbl_()
3.6.5 Initializing and finalizing of program execution
Context and syntax.
int main( int argc, char ** arg) { declarations... first-statement ... [ exit(rc); ] ... return rc; }
Proposed compiler output.
int main( int argn, char ** args) { declarations... DVM_INIT(0,argn,args); // initialization of RTL [ implicit static array creation ] [ tracing of initialized variables ] [ other implicit actions ] first-statement ... [ DVM_EXIT(rc); ] // exit through RTL ... DVM_RETURN(rc); // exit through RTL }
Note. For correct generation the main function must get a command-line parameters (which will be passed to RTL) and must have return or exit statement. Macro DVM_INIT(argn,args) is expanded to
{rtl_init(0L,argn,args); }
Macro DVM_RETURN(r) is expanded to
{lexit_(r);}
Macro DVM_EXIT(r) is expanded to
{lexit_(r);}
Compilation of input-output functions is reduced to renaming of iofun to its RTL analog dvm_iofun. The only exception is fread() and fwrite() functions, when they are applied to a distributed array. In this case the array is read or written as a whole, i.e. size parameter of the function is ignored.
3.7.1 Performance analyzer. Loops
Context and syntax.
[ DVM(PARALLEL... ) ] DO(var,first,last,step) // or FOR(var,times) loop-body
Proposed compiler output.
BPLOOP(n) // for parallel loop or BSLOOP(n) // for sequential loop code for loop ELOOP(n)
Note. The argument n is a serial number of the loop used to identify paired commands. The set of loops for which the macros are generated depends on a command-line options (-e1...-e4). Macro DVM_BPLOOP(n) is expanded to
bploop_(n);
Macro DVM_BSLOOP(n) is expanded to
bsloop_(n);
Macro DVM_ELOOP(n) is expanded to
eloop_(n, line);
3.7.2 Performance analyzer. INTERVAL directive
Context and syntax.
DVM(INTERVAL [ int-expr ] ) { C-statements }
Proposed compiler output.
DVM_BINTER(n,v) { code for statements } DVM_EINTER(n)
Note. The argument n is a serial number of the loop used to identify paired commands. If int-expr does not present, the argument v has some standard value. Macro DVM_BINTER(n,v) is expanded to
binter_(n, v)
Macro DVM_EINTER(n) is expanded to
einter_(n,line )
Context and syntax. Any reference to ordinary or distributed variable var in C-statements or variable initialization.
Proposed compiler output.
DVM_STVA(type,rt,var,base,rhs) // lh-side of assignement DVM_LDV(type,rt,var,base) // for read access DVM_STV(type,rt,var,base) // to register initialization
Note. The set of references, the macros are generated for, depends on a command-line options (-d1...-d4). Macro DVM_LDV(type,rt,var,base) is expanded to
*(type*) ( ( DVM2A((long)&(var),rt) && dldv_(&CDVM_TOP[1], (AddrType *)&CDVM_TOP[0], (long *) base, #var, -1) && 0) ? 0 : )
Macro DVM_STV(type,rt,var,base) is expanded to
( DVM2A((long)&(var), rt), dprstv_(&CDVM_TOP[1], (AddrType *)&CDVM_TOP[0], (long *) base, #var, -1), dstv_())
Macro DVM_STVA(type,rt,var,base,rhs) is expanded to
( DVM2A((long)&(var), rt), dprstv_(&CDVM_TOP[1], (AddrType *)&CDVM_TOP[0], (long *) base, #var, -1), (*(type *)(CDVM_TOP[0]) = rhs), dstv_())
Such an awful construction arised as a result of porting to MS Visual-C 5.0. -- Unusual order of calculation of comma-expression.
3.7.4 Debugger. Computation tracing
Context and syntax. Any loop or task region construct.
Proposed compiler output.
parallel loop creation DVM_PLOOP(n,r,ls,hs,ss) // or DVM_SLOOP(n) loop-headers DVM_ITER(r,vars) code for loop body DVM_ENDLOOP(n)
for loop or
DVM_BTASK(n) // in TASK_REGION header ... DVM_ETASK(n) ON-block or ON-loop body ... DVM_NTASK(ind) // end of TASK_REGION construct
for task region.
Note. Macro DVM_PLOOP(n,r,ls,hs,ss) is expanded to
dbegpl_(r, n, ls, hs, ss);
Parameters are the same as for loop creation. Macro DVM_SLOOP(n) is expanded to
dbegsl_(n);
Macro DVM_ENDLOOP(n) is expanded to
dendl_(n, line);
Macro DVM_ITER(r,vars) is expanded to
diter_(vars, NULL );
Macro DVM_BTASK(n) is expanded to
dbegtr_(n);
Macro DVM_ETASK(n) is expanded to
dendl_(n, );
Macro DVM_NTASK(ind) is expanded to
diter_(ind, 0);
Generation of sequential code is set by the command-line option -s. All DVM-directives ignored except for the following:
Note that preprocessor statements #define should be kept in place unlike the parallel code from which they moved to the beginning if the file.