@@ -274,28 +274,96 @@ reference counters are zero, a delete action is performed.
274
274
275
275
### Types
276
276
277
- There are a few acc dialect type categories to describe:
278
- * type of acc data clause operation input ` varPtr `
279
- - The type of `varPtr` must be pointer-like. This is done by
280
- attaching the `PointerLikeType` interface to the appropriate MLIR
281
- type. Although memory/storage concept is a lower level abstraction,
282
- it is useful because the OpenACC model distinguishes between host
283
- and device memory explicitly - and the mapping between the two is
284
- done through pointers. Thus, by explicitly requiring it in the
285
- dialect, the appropriate language frontend must create storage or
286
- use type that satisfies the mapping constraint.
277
+ Since the ` acc dialect ` is meant to be used alongside other dialects which
278
+ represent the source language, appropriate use of types and type interfaces is
279
+ key to ensuring compatibility. This section describes those considerations.
280
+
281
+ #### Data Clause Operation Types
282
+
283
+ Data clause operations (eg. ` acc.copyin ` ) rely on the following type
284
+ considerations:
285
+ * type of acc data clause operation input ` var `
286
+ - The type of `var` must be one with `PointerLikeType` or `MappableType`
287
+ interfaces attached. The first, `PointerLikeType`, is useful because
288
+ the OpenACC memory model distinguishes between host and device memory
289
+ explicitly - and the mapping between the two is done through pointers. Thus,
290
+ by explicitly requiring it in the dialect, the appropriate language
291
+ frontend must create storage or use type that satisfies the mapping
292
+ constraint. The second possibility, `MappableType` was added because
293
+ memory/storage concept is a lower level abstraction and not all dialects
294
+ choose to use a pointer abstraction especially in the case where semantics
295
+ are more complex (such as `fir.box` which represents Fortran descriptors
296
+ and is defined in the `fir` dialect used from `flang`).
287
297
* type of result of acc data clause operations
288
298
- The type of the acc data clause operation is exactly the same as
289
- `varPtr `. This was done intentionally instead of introducing an
290
- `acc.ref/ptr` type so that IR compatibility and the dialect's
299
+ `var `. This was done intentionally instead of introducing specific `acc`
300
+ output types so that so that IR compatibility and the dialect's
291
301
existing strong type checking can be maintained. This is needed
292
302
since the `acc` dialect must live within another dialect whose type
293
- system is unknown to it. The only constraint is that the appropriate
294
- dialect type must use the `PointerLikeType` interface.
303
+ system is unknown to it.
304
+ * variable type captured in ` varType `
305
+ - When `var`'s type is `PointerLikeType`, the actual type of the target
306
+ may be lost. More specifically, dialects like `llvm` which use opaque
307
+ pointers, do not record the target variable's type. The use of this field
308
+ bridges this gap.
295
309
* type of decomposed clauses
296
310
- Decomposed clauses, such as `acc.bounds` and `acc.declare_enter`
297
311
produce types to allow their results to be used only in specific
298
- operations.
312
+ operations. These are synthetic types solely used for proper IR
313
+ construction.
314
+
315
+ #### Pointer-Like Requirement
316
+
317
+ The need to have pointer-type requirement in the acc dialect stems from
318
+ a few different aspects:
319
+ - Existing dialects like ` hlfir ` , ` fir ` , ` cir ` , ` llvm ` use a pointer
320
+ representation for variables.
321
+ - Reference counters (for data clauses) are described in terms of
322
+ memory. In OpenACC spec 3.3 in section 2.6.7. It says: "A structured reference
323
+ counter is incremented when entering each data or compute region that contain an
324
+ explicit data clause or implicitly-determined data attributes for that section
325
+ of memory". This implies addressability of memory.
326
+ - Attach semantics (2.6.8 attachment counter) are specified using
327
+ "address" terminology: "The attachment counter for a pointer is set to
328
+ one whenever the pointer is attached to new target address, and
329
+ incremented whenever an attach action for that pointer is performed for
330
+ the same target address.
331
+
332
+ #### Type Interfaces
333
+
334
+ The ` acc ` dialect describes two different type interfaces which must be
335
+ implemented and attached to the source dialect's types in order to allow use
336
+ of data clause operations (eg. ` acc.copyin ` ). They are as follows:
337
+ * ` PointerLikeType `
338
+ - The idea behind this interface is that variables end up being represented
339
+ as pointers in many dialects. More specifically, ` fir ` , ` cir ` , ` llvm `
340
+ represent user declared local variables with some dialect specific form of
341
+ ` alloca ` operation which produce pointers. Globals, similarly, are referred by
342
+ their address through some form of ` address_of ` operation. Additionally, an
343
+ implementation for OpenACC runtime needs to distinguish between device and
344
+ host memory - also typically done by talking about pointers. So this type
345
+ interface requirement fits in naturally with OpenACC specification. Data
346
+ mapping operation semantics can often be simply described by a pointer and
347
+ size of the data it points to.
348
+ * ` MappableType `
349
+ - This interface was introduced because the ` PointerLikeType ` requirement
350
+ cannot represent cases when the source dialect does not use pointers. Also,
351
+ some cases, such as Fortran descriptor-backed arrays and Fortran optional
352
+ arguments, require decomposition into multiple steps. For example, in the
353
+ descriptor case, mapping of descriptor is needed, mapping of the data, and
354
+ implicit attach into device descriptor. In order to allow capturing all of
355
+ this complexity with a single data clause operation, the ` MappableType `
356
+ interface was introduced. This is consistent with the dialect's goals
357
+ including being "able to regenerate the semantic equivalent of the user
358
+ pragmas".
359
+
360
+ The intent is that a dialect's type system implements one of these two
361
+ interfaces. And to be precise, a type should only implement one or the other
362
+ (and not both) - since keeping them separate avoids ambiguity on what actually
363
+ needs mapped. When ` var ` is ` PointerLikeType ` , the assumption is that the data
364
+ pointed-to will be mapped. If the pointer-like type also implemented
365
+ ` MappableType ` interface, it becomes ambiguous whether the data pointed to or
366
+ the pointer itself is being mapped.
299
367
300
368
### Recipes
301
369
0 commit comments