@@ -274,28 +274,96 @@ reference counters are zero, a delete action is performed.
274274
275275### Types
276276
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`).
287297* type of result of acc data clause operations
288298 - 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
291301 existing strong type checking can be maintained. This is needed
292302 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.
295309* type of decomposed clauses
296310 - Decomposed clauses, such as `acc.bounds` and `acc.declare_enter`
297311 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.
299367
300368### Recipes
301369
0 commit comments