source: CIVL/mods/dev.civl.com/notes/mp.txt@ 1aaefd4

main test-branch
Last change on this file since 1aaefd4 was aad342c, checked in by Stephen Siegel <siegel@…>, 3 years ago

Performing huge refactor to incorporate ABC, GMC, and SARL into CIVL repo and use Java modules.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5664 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 8.2 KB
RevLine 
[0596330]1Message passing notes.
2
3Scoping goals:
4 - it should be possible to statically determine the scope
5 of any expression. That means the expression only references
6 objects in that scope.
7 - it should be possible to specify/verify the "read scope"
8 and "write scope" of any procedure.
9 - the goals above are complicated by pointers, which can
10 potentially to point to any scope if not controlled.
11 So there must be ways to specify/verify some restrictions
12 on the scopes of pointers.
13
14Scopes:
15
16First, scopes are declared like variable declarations:
17
18{ ...
19 $scope s;
20 ...
21}
22
23gives a name to that scope. In fact, every scope has a name
24automatically, this just gives the program a way to refer to it.
25
26Scopes cannot be used in expressions except as specified
27below. In particular they cannot be assigned
28or passed as arguments to functions.
29
30Pointer types:
31
32Given any object type T, there is a type "pointer-to-T".
33Given in addition a scope s, there is a type "pointer-to-T-in-s".
34The type "pointer-to-T-in-s" is a subtype of "pointer-to-T".
35The type "pointer-to-T" is identical to the type
36"pointer-to-T-in-s0", where s0 is the system (most global) scope.
37
38Furthermore, if s1 is contained in s2, "pointer-to-T-in-s1"
39is a subtype of "pointer-to-T-in-s2".
40
41Syntax: a variable is declared to have type
42"pointer-to-int-in-s", for example, as follows:
43
44 int *<s> t;
45
46In general, the scope modifier is always placed after the
47* and surrounded by angle brackets.
48
49Address-of: the address-of operator (&) returns a pointer
50of the appropriate subtype using the innermost scope
51in which its lhs argument is declared. For example:
52
53{
54 $scope s1;
55 int x;
56 double a[N];
57 int *<s1> p = &x;
58 double *<s1> q = &a[2];
59}
60
61is legal (it will type-check) because &x has type
62pointer-to-int-in-s1, since s1 is the scope in which x
63is declared. Etc.
64
65Pointer addition: if p has type pointer-to-T-in-s,
66then p+i (for an integer i) has type pointer-to-T-in-s.
67I.e., pointer addition cannot leave the scope.
68(in fact, it cannot leave the object).
69
70Pointer subtraction: pointer subtraction is
71defined on two pointers of the same type, where "same"
72includes the scope.
73
74Pointer casts: if scope s1 is contained in scope s2,
75an expression of type pointer-to-T-in-s1 can always
76be cast to pointer-to-T-in-s2, because the first
77is a subtype of the second. This is checked
78statically. The cast in the other direction is also OK,
79but will only be checked at runtime. If neither s1 is
80contained in s2 nor s2 is contained in s1, a cast from
81one pointer type to the other is illegal and will be
82reported as a syntax error statically.
83
84A type pointer-to-T1-in-s can be cast to a type
85pointer-to-T2-in-s according to the usual rules
86of C (or whatever variation is used in CIVL-C).
87In other words, usual casting rules apply as long
88as you don't change the scope.
89
90Parameterized typedefs:
91
92typedefs can be parameterized by scopes, e.g.
93
94<s> typedef struct message_struct {
95 int size;
96 void *<s> data;
97} Message;
98
99When the typedef is used, you specify the scope parameters:
100
101Message<s1> buffer[N];
102
103For each scope s, you get a different type Message<s>.
104There is no (subtype or other) relaltionship between
105Message<s1> and Message<s2> and you cannot cast from one
106to the other.
107
108Multiple scope can be used as parameters:
109
110<s1,s2,s3> typedef struct ...
111
112
113Prameterized procedures:
114
115procedures can be parameterized by scopes, for example, as follows:
116
117<s> int *<s> f(int *<s> p);
118
119This means: for any scope s, f takes a pointer-to-int-in-s and
120returns a pointer-to-int-in-s. Multiple scopes can be used
121as parameters: <s,t> ....
122
123The procedure f is invoked by specifying the scope as follows
124 ... f<s1>(...) ...
125Eventually we can infer the s in most cases.
126
127Procedure contracts: Procedure contracts
128can be optionally associated to procedure declarations
129or definitions in CIVL-C. There will be typical
130requires/ensures and other clauses in these contracts.
131In addition, the following two kinds of clauses
132can be used:
133
134 $reads s1;
135 $writes s2;
136
137where s1 and s2 are scopes. This means that any object
138read in any execution of f must lie in scope s1 and any
139object modified in any execution of f must lie is scope
140s2. The scopes s1 and s2 can be parameters, as in:
141
142<s1,s2> double *<s2> f(int *<s1> p)
143 $reads s1;
144 $writes s2;
145 {
146 ...
147 }
148
149
150Heaps:
151
152A heap is declared using the built-in type $heap:
153{ ... $heap h1; ...}
154
155However, a heap cannot be assigned or used in expressions,
156with one exception: it can be the argument of address-of (&).
157Hence this is fine:
158
159{ ...
160 $scope s1;
161 $heap h1;
162 $heap *<s1> p = &h1;
163 ...
164}
165
166Malloc and free: these built-in functions have the following
167signatures:
168
169<s> void *<s> $malloc($heap *<s> heap, int size)
170 $reads s;
171 $writes s;
172
173<s> void $free($heap *<s> heap, void *<s> ptr)
174 $reads s;
175 $writes s;
176
177This means:
178 - for any scope s, $malloc takes a pointer-to-heap-in-s,
179 and an integer size, and returns a pointer-to-void-in-s.
180 - $free takes a pointer-to-heap-in-s and a pointer-to-void-in-s,
181 and returns nothing.
182 - both procedures can only read and modify s.
183
184A runtime error will be generated if the second argument
185to $free is not really a pointer to the heap specified in
186the first argument.
187
188It may be that the first argument to $free is unnecessary.
189However, it helps keep track of what is modified by the procedure
190(namely, the heap that that arguments points to). At the very
191least, we need to keep track of the scope of the heap.
192Possibly, we could get by with:
193
194<s> void $free(void *<s> ptr)
195 $reads s;
196 $writes s;
197
198
199Memcpy: this is another built-in function with signature:
200
201 <s,t> void memcpy(void *<s> p, void *<t> q, size_t size)
202 $reads t;
203 $writes s;
204
205This copies data from q to p as usual.
206
207
208Examples:
209
210{
211 $scope shared;
212 $heap shared_heap;
213 double *<shared> p = $malloc<shared>(&shared_heap, n*sizeof(double));
214 double *<shared> q = $malloc<shared>(&shared_heap, n*sizeof(double));
215
216 for (int i=0; i<n; i++) p[i] = (double)i;
217 $memcpy<shared,shared>(p, q, n*sizeof(double));
218 $free<shared>(&shared_heap, p);
219 $free<shared>(&shared_heap, q);
220}
221
222Here is how an MPI program can be modeled with every process
223getting its own heap:
224
225void MPI_proc(int pid) {
226 $scope proc_scope;
227 $heap proc_heap;
228 ...
229 ... $malloc<proc_scope>(&proc_heap, size) ...
230 ...
231}
232
233void main(int nprocs) {
234 $proc procs[nprocs];
235
236 for (int i=0; i<nprocs; i++)
237 procs[i] = $spawn MPI_proc(i);
238 ...
239}
240
241------------------------------------------------------------
242
243First attempt
244
245$input int NPROCS;
246$assume NPROCS >= 1;
247$scope top;
248$heap mp_heap;
249
250typedef struct Message {
251 struct Message *<top> next;
252 struct Message *<top> prev;
253 int tag;
254 int size;
255 void *<top> data;
256}
257
258typedef struct Comm {
259 int nprocs;
260
261
262
263-------------------------------------------------------------
264
265<s> typedef struct _CIVL_Message {
266 struct _CIVL_Message *<s> next; // next message in this queue
267 struct _CIVL_Message *<s> prev; // previous message in this queue
268 int tag; // message tag
269 int size; // number of elements
270 void *<s> data; // pointer to first element
271} CIVL_Message;
272
273<s> typedef struct _CIVL_Comm {
274 $heap heap;
275 int numProcs; // number of procs in this communicator
276 $proc *<s> procs; // array of length numProcs
277 CIVL_Message *<s>*<s>*<s> buf_front; // oldest element of each msg queue
278 CIVL_Message *<s>*<s>*<s> buf_back; // newest element of each msg queue
279} CIVL_Comm;
280
281<s> CIVL_Comm CIVL_Comm_create(int nprocs, $proc *<s> procs)
282{ YOU CAN'T DO THIS: if you want the scope of comm to be s,
283 you need a pointer to a heap in s...............
284 Alternatively, declare this within the scope
285
286 CIVL_Comm<s> comm;
287
288 comm.numProcs = nprocs;
289 comm.procs = $malloc(&comm.heap, nprocs*sizeof(int));
290 for (int i=0; i<nprocs; i++) comm.procs[i] = procs[i];
291 comm.buf_front =
292 (CIVL_Message *<s>*<s>*<s>)
293 $malloc(&comm.heap, nprocs*sizeof(CIVL_Message *<s>*<s>));
294 for (int i=0; i<nprocs; i++) {
295 comm.buf_front[i] =
296 (CIVL_Message *<s>*<s>)
297 $malloc(&comm.heap, nprocs*sizeof(CIVL_Message *<s>));
298 for (int j=0; j<nprocs; j++)
299 comm.buf_front[i][j] = NULL;
300 }
301 // ditto for comm.buf_back
302 return comm;
303}
304
305<s> send(int source, void *<s> buf, int size, int dest, int tag,
306 CIVL_Comm<s>)
307 $reads s;
308 $writes s;
309{
310
311}
Note: See TracBrowser for help on using the repository browser.