[Chapel Merge] Serialize and forward promotion iterator records

Branch: refs/heads/main
Revision: 8ea37a3
Author: e-kayrakli
Link: Serialize and forward promotion iterator records by e-kayrakli · Pull Request #18881 · chapel-lang/chapel · GitHub
Log Message:

Merge pull request #18881 from e-kayrakli/transitive-serialization

Serialize and forward promotion iterator records

This PR generates serializers for promotion-based iterator records.

Resolves https://github.com/Cray/chapel-private/issues/1785

The main purpose of the PR is to reduce communication counts with serialized
slices. However, we first want to get some nightly testing going in this PR before
we enable slice serialization by default.

Enable slice serialization by default by e-kayrakli · Pull Request #18911 · chapel-lang/chapel · GitHub will enable slice serialization.

Implementation Overview

At function resolution;

  • We mark iterator records that are created from promotion wrappers.
  • While resolving serializers, we automatically create serializers for them if
    their fields are serializeable.

At remote value forwarding;

  • We specifically handle deserializers for types that have ref fields, before
    injecting deserialization.

Details

  • Iterator records that were created from promotion wrappers now have
    FLAG_PROMOTION_ITERATOR_RECORD on their type.
  • Iterator records don't have all of their fields finalized at resolution time.
    Therefore, we add "protofields" based on the promotion wrapper's formals. This
    is similar to PRIM_ITERATOR_RECORD_FIELD_VALUE_BY_FORMAL.
    • These fields help create serializers and deserializers.
    • These protofields are replaced with the final fields at iterator lowering.
      At that time we remove those fields from the record.
    • These fields are marked with FLAG_PROMOTION_PROTO_FIELD.
  • When writing deserializers at resolution, we don't yet know whether fields
    will be val or ref. There's an optimization (replaceRecordWrapperRefs, more
    on this later) that kicks in right before remote value forwarding that does
    final adjustments.
    • So, we create the deserializers as:
    proc type chpl__deserialize(data) {
      var ret: this;
      if deserialization_marker {
         ret.field = ret.field.type.chpl__deserialize(data[idx])
      }
      else {
        ret.field = PRIM_REF_DESERIALIZE(ret.field.type, data, idx);
      }
    }
    
    Then,
    • later during resolution: we replace that primitive with chpl__deserilize
      call, and pretend it is resolved (although the arguments to it wouldn't
      resolve normally. This trips up --verify, the PR works around that)
    • at remote value forwarding: we accept the then branch and discard the
      rest if the field turns out to be a val field, or hoist the then branch
      outside the call to chpl__deserialize, pass the result of the field
      deserialization back to chpl__deserialize` by ref, and modify this
      deserializer to handle the additional argument.
    • This repeats for all fields, and recursively looks into fields.
  • The conditional's flag has FLAG_DESERIALIZATION_BLOCK_MARKER
  • As serializers are inserted at the point of definition of the type itself,
    flattenFunctions now removes those nested functions as it removes nested
    types.
  • replaceRecordWrappedRefs is adjusted to not modify types with serializers.
    This optimization looks pretty reliant on privatization, and I don't think it
    needs to do anything if a type is serialized and forwarded.
  • Distributed array types' chpl__serialize will no longer resolve if the
    element type has runtime component.
  • AST cleanup now removes serializers for dead types.

Limitations

  • Currently, this is only limited to promotions. There might be a more general
    applicability for loop expressions. But I am not sure if that's needed.

[Reviewed by @mppf]

Test:

  • [x] gasnet

  • [x] gasnet -schpl_serializeSlices=true

  • [x] gasnet verify release/examples, distributions/robust

  • [x] gasnet asan release/examples, distributions/robust

  • [x] gasnet memleaks release/examples, distributions/robust

  • [x] standard

    Modified Files:
    A test/optimizations/remoteValueForwarding/zippedSlices/COMPOPTS
    A test/optimizations/remoteValueForwarding/zippedSlices/NUMLOCALES
    A test/optimizations/remoteValueForwarding/zippedSlices/SKIPIF
    A test/optimizations/remoteValueForwarding/zippedSlices/promotion.chpl
    A test/optimizations/remoteValueForwarding/zippedSlices/promotion.good
    A test/optimizations/remoteValueForwarding/zippedSlices/promotionMany.chpl
    A test/optimizations/remoteValueForwarding/zippedSlices/promotionMany.good
    R test/optimizations/remoteValueForwarding/zippedSlices/sliceCombos.compopts
    R test/optimizations/remoteValueForwarding/zippedSlices/sliceCombos.numlocales
    R test/optimizations/remoteValueForwarding/zippedSlices/sliceCombos.skipif
    M compiler/AST/baseAST.cpp
    M compiler/AST/iterator.cpp
    M compiler/AST/primitive.cpp
    M compiler/AST/type.cpp
    M compiler/include/type.h
    M compiler/main/checks.cpp
    M compiler/next/include/chpl/uast/PragmaList.h
    M compiler/next/include/chpl/uast/PrimOpsList.h
    M compiler/optimizations/remoteValueForwarding.cpp
    M compiler/passes/flattenFunctions.cpp
    M compiler/passes/parallel.cpp
    M compiler/resolution/functionResolution.cpp
    M compiler/resolution/lowerIterators.cpp
    M compiler/resolution/resolveFunction.cpp
    M modules/dists/BlockCycDist.chpl
    M modules/dists/BlockDist.chpl
    M modules/dists/CyclicDist.chpl
    M modules/dists/StencilDist.chpl
    M modules/internal/ArrayViewRankChange.chpl
    M modules/internal/ArrayViewReindex.chpl
    M test/distributions/robust/arithmetic/performance/multilocale/rvfSlices/sliceOps.block.good
    M test/distributions/robust/arithmetic/performance/multilocale/rvfSlices/sliceOps.block.na-none.good
    M test/distributions/robust/arithmetic/performance/multilocale/rvfSlices/sliceOps.cyclic.good
    M test/distributions/robust/arithmetic/performance/multilocale/rvfSlices/sliceOps.cyclic.na-none.good

    Compare: Comparing e82366490103...8ea37a3c6868 · chapel-lang/chapel · GitHub