1 /*
2  * Copyright (c) 1994-2018, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #ifndef FE_COMM_H
19 #define FE_COMM_H
20 
21 #include "gbldefs.h"
22 #include "transfrm.h"
23 #include <stdio.h>
24 
25 /*
26  * Data structure to record information about subscripts
27  */
28 
29 typedef struct {
30   int idx;        /* ASTLI for forall index triplet or 0 */
31   int stride;     /* multiplier of idx */
32   int base;       /* constant */
33   int sub;        /* ast for the subscript */
34   int lhs_dim;    /* lhs dimension aligned with the same templ dim */
35   int newl;       /* new lower bound for forall */
36   int newu;       /* new upper bound for forall */
37   int news;       /* new stride for forall */
38   int dst_type;   /* distribution type */
39   int comm_type;  /* communications type */
40   int comm_value; /* generic value for comms */
41   int diff;       /* f2(sub2)-f1(sub1) alignment function difference */
42   int cnst;       /* to show difference has no index value */
43   int lof;        /* cyclic distribution, a(i-lof) */
44   int dupl;       /* duplicate, idx appear more than one, a(i,i) */
45   int nop;        /* negative overlap*/
46   int pop;        /* pozitive overlap*/
47 } SUBINFO;
48 
49 #define COMMT_NOTAG -1    /* no tag attached yet */
50 #define COMMT_NONE 0      /* no communication */
51 #define COMMT_MULTI 1     /* multicast */
52 #define COMMT_SHIFTC 2    /* constant shift */
53 #define COMMT_SHIFTV 3    /* variable shift */
54 #define COMMT_TRANSFER 4  /* transfer */
55 #define COMMT_REPLICATE 5 /* replication */
56 #define COMMT_CONST 6     /* index */
57 #define COMMT_UNSTRUCT 7  /* unstructured communication */
58 
59 #define SUBI_IDX(i) trans.subb.stg_base[i].idx
60 #define SUBI_STRIDE(i) trans.subb.stg_base[i].stride
61 #define SUBI_BASE(i) trans.subb.stg_base[i].base
62 #define SUBI_SUB(i) trans.subb.stg_base[i].sub
63 #define SUBI_DSTT(i) trans.subb.stg_base[i].dst_type
64 #define SUBI_LDIM(i) trans.subb.stg_base[i].lhs_dim
65 #define SUBI_NEWL(i) trans.subb.stg_base[i].newl
66 #define SUBI_NEWU(i) trans.subb.stg_base[i].newu
67 #define SUBI_NEWS(i) trans.subb.stg_base[i].news
68 #define SUBI_DSTT(i) trans.subb.stg_base[i].dst_type
69 #define SUBI_COMMT(i) trans.subb.stg_base[i].comm_type
70 #define SUBI_COMMV(i) trans.subb.stg_base[i].comm_value
71 #define SUBI_CNST(i) trans.subb.stg_base[i].cnst
72 #define SUBI_DIFF(i) trans.subb.stg_base[i].diff
73 #define SUBI_LOF(i) trans.subb.stg_base[i].lof
74 #define SUBI_DUPL(i) trans.subb.stg_base[i].dupl
75 #define SUBI_NOP(i) trans.subb.stg_base[i].nop
76 #define SUBI_POP(i) trans.subb.stg_base[i].pop
77 
78 typedef struct {
79   int result;
80   int base;
81   int operator;
82   int function;
83   int mask;
84   int array;
85   int array_simple;
86 } SCATTER_TYPE;
87 
88 struct comminfo {
89   int std;
90   int subinfo;
91   int lhs;
92   int sub;
93   int forall;
94   int asn;
95   int unstruct;
96   int mask_phase;
97   int ugly_mask;
98   SCATTER_TYPE scat;
99   int usedstd;
100 };
101 
102 extern struct comminfo comminfo;
103 
104 #define NO_CLASS 0
105 #define NO_COMM 1
106 #define OVERLAP 2
107 #define COLLECTIVE 3
108 #define COPY_SECTION 4
109 #define GATHER 5
110 #define SCATTER 6
111 #define IRREGULAR 7
112 
113 typedef struct {
114   int class;  /* communication class */
115   int flag;   /* flag for overlap shift */
116   int temp;   /* pointer to the temp for this ref */
117   int arrsym; /* symbol pointer for the array */
118   int arr;    /* array ast */
119   int sub;    /* first subscript */
120   int ndim;   /* number of dimensions */
121   int next;   /* next subscript */
122 } ARREF;
123 
124 #define ARREF_CLASS(i) trans.arrb.stg_base[i].class
125 #define ARREF_FLAG(i) trans.arrb.stg_base[i].flag
126 #define ARREF_TEMP(i) trans.arrb.stg_base[i].temp
127 #define ARREF_ARRSYM(i) trans.arrb.stg_base[i].arrsym
128 #define ARREF_ARR(i) trans.arrb.stg_base[i].arr
129 #define ARREF_SUB(i) trans.arrb.stg_base[i].sub
130 #define ARREF_NDIM(i) trans.arrb.stg_base[i].ndim
131 #define ARREF_NEXT(i) trans.arrb.stg_base[i].next
132 
133 typedef struct {
134   int lhs; /* left hand side array ref */
135   int rhs; /* list of rhs array refs */
136 } TDESC;
137 
138 #define TD_LHS(i) trans.tdescb.stg_base[i].lhs
139 #define TD_RHS(i) trans.tdescb.stg_base[i].rhs
140 
141 typedef struct {
142   struct {
143     SUBINFO *stg_base;
144     int stg_size;
145     int stg_avail;
146   } subb;
147   struct {
148     ARREF *stg_base;
149     int stg_size;
150     int stg_avail;
151   } arrb;
152   struct {
153     TDESC *stg_base;
154     int stg_size;
155     int stg_avail;
156   } tdescb;
157   int iardt;           /* array of integer datatype */
158   int first;           /* first statement available */
159   int dtmp;            /* temp array/pointer to access data structs */
160   TLIST *ar_type_list; /* list of array types */
161   FILE *ctrfile;       /* constructor file */
162   int cmnblksym;       /* common block name */
163   int initsym;         /* init subroutine name */
164   int rhsbase;         /* first array ref in RHS */
165   int lhs;             /* lhs array ref */
166   int darray;          /* comm descriptor array (temporary) */
167 } TRANSFORM;
168 
169 extern TRANSFORM trans;
170 
171 #define FORALL_PFX "i_"
172 #define TMPL_PFX "tmpl_"
173 #define PROC_PFX "proc_"
174 #define INIT_PFX "init_"
175 #define COMMON_PFX "cmn_"
176 
177 /* storage allocation macros  */
178 
179 #define TRANS_ALLOC(stgb, dt, sz) \
180   {                               \
181     NEW(stgb.stg_base, dt, sz);   \
182     stgb.stg_size = sz;           \
183     stgb.stg_avail = 1;           \
184   }
185 
186 #define TRANS_MORE(stb, dt, nsz)                                            \
187   {                                                                         \
188     stb.stg_base =                                                          \
189         (dt *)sccrelal((char *)stb.stg_base, ((BIGUINT64)((nsz) * sizeof(dt)))); \
190     stb.stg_size = nsz;                                                     \
191     if (stb.stg_base == NULL)                                               \
192       error(7, 4, 0, CNULL, CNULL);                                         \
193   }
194 
195 #define TRANS_NEED(stb, dt, nsz)    \
196   if (stb.stg_avail > stb.stg_size) \
197     TRANS_MORE(stb, dt, nsz);
198 
199 #define TRANS_FREE(stb) FREE(stb.stg_base)
200 
201 LOGICAL is_same_number_of_idx(int dest, int src, int list);
202 LOGICAL normalize_bounds(int sptr);
203 int add_lbnd(int dtyp, int dim, int ast, int astmember);
204 int insert_endmask(int ast, int stdstart);
205 int insert_mask(int ast, int stdstart);
206 int record_barrier(LOGICAL, int, int);
207 int sub_lbnd(int dtyp, int dim, int ast, int astmember);
208 void check_region(int std);
209 void comm_analyze(void);
210 void comm_fini(void);
211 void init_region(void);
212 void report_comm(int std, int cause);
213 int reference_for_temp(int sptr, int a, int forall);
214 int emit_get_scalar(int a, int std);
215 void forall_opt1(int ast);
216 void transform_forall(int std, int ast);
217 void scalarize(int std, int forall, LOGICAL after_transformer);
218 void un_fuse(int forall);
219 void sequentialize(int std, int forall, LOGICAL after_transformer);
220 
221 #endif /* FE_COMM_H */
222