Fix problems with NetworkAtomics from r23794

r22107 fixed some wrong return types for Atomics.chpl,
and r23435 and r23472 fixed that for NetworkAtomics.chpl,
but my patch r23794 inadverdently undid some of these changes.

Here I put the changes back. Some other notes:
 - I added explicit return types to read and peek methods.
   That seemed to make it fit in better but the corresponding
   change would also need to be done in Atomics.chpl for peek.

 - I did not add :void return types to e.g. add or sub methods,
   but somebody could do that if it's important to match the style
   used in Atomics.chpl

 - I fixed peek and poke for ratomicflag to work with bool instead
   of int(64).

Tested with 'make check'.

pragma "atomic module"
pragma "no use ChapelStandard"
module NetworkAtomics {
  const LINENO = -1:int(32); // it'd be nice if we had something like __LINENO__

  // int(64)
  extern proc chpl_comm_atomic_get_int64(ref result:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_int64(ref desired:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_int64(ref op:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_int64(ref op:int(64),
                                               l:int(32), ref obj:int(64),
                                               ref result:int(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_int64(ref op:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_int64(ref op:int(64),
                                               l:int(32), ref obj:int(64),
                                               ref result:int(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_and_int64(ref op:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_and_int64(ref op:int(64),
                                               l:int(32), ref obj:int(64),
                                               ref result:int(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_or_int64(ref op:int(64),
                                        l:int(32), ref obj:int(64),
                                        ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_or_int64(ref op:int(64),
                                              l:int(32), ref obj:int(64),
                                              ref result:int(64),
                                              ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xor_int64(ref op:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_xor_int64(ref op:int(64),
                                               l:int(32), ref obj:int(64),
                                               ref result:int(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_int64(ref desired:int(64),
                                          l:int(32), ref obj:int(64),
                                          ref result:int(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_int64(ref expected:int(64),
                                             ref desired:int(64),
                                             l:int(32), ref obj:int(64),
                                             ref result:bool(32),
                                             ln:int(32), fn:string);

  // int(64)
  pragma "atomic type"
  record ratomic_int64 {
    var _v: int(64);
    inline proc read(order:memory_order = memory_order_seq_cst):int(64) {
      var ret: int(64);
      chpl_comm_atomic_get_int64(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:int(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var ret:int(64);
      var v = value;
      chpl_comm_atomic_xchg_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:int(64), desired:int(64),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_int64(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:int(64), desired:int(64),
                                    order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:int(64), desired:int(64),
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_add_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:int(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_add_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_sub_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:int(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_sub_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_or_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc or(value:int(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_or_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchAnd(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_and_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc and(value:int(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_and_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchXor(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_xor_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc xor(value:int(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_xor_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc waitFor(val:int(64), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        // After waiting for the value, do a thread fence
        // in order to guarantee e.g. an acquire barrier even
        // if the on statement is not included.
        atomic_thread_fence(order);
      }
    }

    inline proc peek():int(64) {
      return _v;
    }
    inline proc poke(value:int(64)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_int64, b:ratomic_int64) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_int64, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_int64, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_int64, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_int64, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_int64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_int64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // int(32)
  extern proc chpl_comm_atomic_get_int32(ref result:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_int32(ref desired:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_int32(ref op:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_int32(ref op:int(32),
                                               l:int(32), ref obj:int(32),
                                               ref result:int(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_int32(ref op:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_int32(ref op:int(32),
                                               l:int(32), ref obj:int(32),
                                               ref result:int(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_and_int32(ref op:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_and_int32(ref op:int(32),
                                               l:int(32), ref obj:int(32),
                                               ref result:int(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_or_int32(ref op:int(32),
                                        l:int(32), ref obj:int(32),
                                        ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_or_int32(ref op:int(32),
                                              l:int(32), ref obj:int(32),
                                              ref result:int(32),
                                              ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xor_int32(ref op:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_xor_int32(ref op:int(32),
                                               l:int(32), ref obj:int(32),
                                               ref result:int(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_int32(ref desired:int(32),
                                          l:int(32), ref obj:int(32),
                                          ref result:int(32),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_int32(ref expected:int(32),
                                             ref desired:int(32),
                                             l:int(32), ref obj:int(32),
                                             ref result:bool(32),
                                             ln:int(32), fn:string);

  // int32
  pragma "atomic type"
  record ratomic_int32 {
    var _v: int(32);
    inline proc read(order:memory_order = memory_order_seq_cst):int(32) {
      var ret: int(32);
      chpl_comm_atomic_get_int32(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:int(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var ret:int(32);
      var v = value;
      chpl_comm_atomic_xchg_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:int(32), desired:int(32),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_int32(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:int(32), desired:int(32),
                                    order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:int(32), desired:int(32),
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_add_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:int(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_add_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_sub_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:int(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_sub_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_or_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc or(value:int(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_or_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchAnd(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_and_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc and(value:int(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_and_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchXor(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_xor_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc xor(value:int(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_xor_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc waitFor(val:int(32), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek():int(32) {
      return _v;
    }
    inline proc poke(value:int(32)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_int32, b:ratomic_int32) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_int32, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_int32, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_int32, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_int32, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_int32, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_int32, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // uint(64)
  extern proc chpl_comm_atomic_get_uint64(ref result:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_uint64(ref desired:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_uint64(ref op:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_uint64(ref op:uint(64),
                                               l:int(32), ref obj:uint(64),
                                               ref result:uint(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_uint64(ref op:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_uint64(ref op:uint(64),
                                               l:int(32), ref obj:uint(64),
                                               ref result:uint(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_and_uint64(ref op:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_and_uint64(ref op:uint(64),
                                               l:int(32), ref obj:uint(64),
                                               ref result:uint(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_or_uint64(ref op:uint(64),
                                        l:int(32), ref obj:uint(64),
                                        ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_or_uint64(ref op:uint(64),
                                              l:int(32), ref obj:uint(64),
                                              ref result:uint(64),
                                              ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xor_uint64(ref op:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_xor_uint64(ref op:uint(64),
                                               l:int(32), ref obj:uint(64),
                                               ref result:uint(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_uint64(ref desired:uint(64),
                                          l:int(32), ref obj:uint(64),
                                          ref result:uint(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_uint64(ref expected:uint(64),
                                             ref desired:uint(64),
                                             l:int(32), ref obj:uint(64),
                                             ref result:bool(32),
                                             ln:int(32), fn:string);

  // uint(64)
  pragma "atomic type"
  record ratomic_uint64 {
    var _v: uint(64);
    inline proc read(order:memory_order = memory_order_seq_cst):uint(64) {
      var ret: uint(64);
      chpl_comm_atomic_get_uint64(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:uint(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var ret:uint(64);
      var v = value;
      chpl_comm_atomic_xchg_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:uint(64), desired:uint(64),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_uint64(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:uint(64), desired:uint(64),
                                    order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:uint(64), desired:uint(64),
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_add_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:uint(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_add_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_sub_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:uint(64), order:memory_order = memory_order_seq_cst){
      var v = value;
      chpl_comm_atomic_sub_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_or_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc or(value:uint(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_or_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchAnd(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_and_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc and(value:uint(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_and_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchXor(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_xor_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc xor(value:uint(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_xor_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc waitFor(val:uint(64), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek():uint(64) {
      return _v;
    }
    inline proc poke(value:uint(64)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_uint64, b:ratomic_uint64) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_uint64, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_uint64, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_uint64, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_uint64, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_uint64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_uint64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // uint(32)
  extern proc chpl_comm_atomic_get_uint32(ref result:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_uint32(ref desired:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_uint32(ref op:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_uint32(ref op:uint(32),
                                               l:int(32), ref obj:uint(32),
                                               ref result:uint(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_uint32(ref op:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_uint32(ref op:uint(32),
                                               l:int(32), ref obj:uint(32),
                                               ref result:uint(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_and_uint32(ref op:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_and_uint32(ref op:uint(32),
                                               l:int(32), ref obj:uint(32),
                                               ref result:uint(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_or_uint32(ref op:uint(32),
                                        l:int(32), ref obj:uint(32),
                                        ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_or_uint32(ref op:uint(32),
                                              l:int(32), ref obj:uint(32),
                                              ref result:uint(32),
                                              ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xor_uint32(ref op:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_xor_uint32(ref op:uint(32),
                                               l:int(32), ref obj:uint(32),
                                               ref result:uint(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_uint32(ref desired:uint(32),
                                          l:int(32), ref obj:uint(32),
                                          ref result:uint(32),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_uint32(ref expected:uint(32),
                                             ref desired:uint(32),
                                             l:int(32), ref obj:uint(32),
                                             ref result:bool(32),
                                             ln:int(32), fn:string);

  // uint(32)
  pragma "atomic type"
  record ratomic_uint32 {
    var _v: uint(32);
    inline proc read(order:memory_order = memory_order_seq_cst):uint(32) {
      var ret: uint(32);
      chpl_comm_atomic_get_uint32(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:uint(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var ret:uint(32);
      var v = value;
      chpl_comm_atomic_xchg_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:uint(32), desired:uint(32),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_uint32(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:uint(32), desired:uint(32),
                                    order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:uint(32), desired:uint(32),
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_add_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:uint(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_add_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_sub_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:uint(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_sub_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_or_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc or(value:uint(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_or_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchAnd(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_and_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc and(value:uint(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_and_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchXor(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_xor_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc xor(value:uint(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_xor_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc waitFor(val:uint(32), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek():uint(32) {
      return _v;
    }
    inline proc poke(value:uint(32)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_uint32, b:ratomic_uint32) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_uint32, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_uint32, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_uint32, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_uint32, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_uint32, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_uint32, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // bool, implemented with int(64)
  pragma "atomic type"
  record ratomicflag {
    var _v: int(64);
    inline proc read(order:memory_order = memory_order_seq_cst):bool {
      var ret: int(64);
      chpl_comm_atomic_get_int64(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret:bool;
    }
    inline proc write(value:bool, order:memory_order = memory_order_seq_cst) {
      var v = value:int(64);
      chpl_comm_atomic_put_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:bool, order:memory_order = memory_order_seq_cst):bool {
      var ret:int(64);
      var v = value:int(64);
      chpl_comm_atomic_xchg_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret:bool;
    }
    inline proc compareExchange(expected:bool, desired:bool,
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected:int(64);
      var td = desired:int(64);
      chpl_comm_atomic_cmpxchg_int64(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
inline proc compareExchangeWeak(expected:bool, desired:bool,
                                order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:bool, desired:bool,
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc testAndSet():bool {
      return this.exchange(true);
    }
    inline proc clear() {
      this.write(false);
    }

    inline proc waitFor(val:bool, order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek():bool {
      return _v:bool;
    }
    inline proc poke(value:bool) {
      _v = value:int(64);
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomicflag, b:ratomicflag) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomicflag, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomicflag, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomicflag, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomicflag, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomicflag, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomicflag, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // real(64)
  extern proc chpl_comm_atomic_get_real64(ref result:real(64),
                                          l:int(32), ref obj:real(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_real64(ref desired:real(64),
                                          l:int(32), ref obj:real(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_real64(ref op:real(64),
                                          l:int(32), ref obj:real(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_real64(ref op:real(64),
                                                l:int(32), ref obj:real(64),
                                                ref result:real(64),
                                                ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_real64(ref op:real(64),
                                          l:int(32), ref obj:real(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_real64(ref op:real(64),
                                                l:int(32), ref obj:real(64),
                                                ref result:real(64),
                                                ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_real64(ref desired:real(64),
                                           l:int(32), ref obj:real(64),
                                           ref result:real(64),
                                           ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_real64(ref expected:real(64),
                                              ref desired:real(64),
                                              l:int(32), ref obj:real(64),
                                              ref result:bool(32),
                                              ln:int(32), fn:string);

  pragma "atomic type"
  record ratomic_real64 {
    var _v: real(64);
    inline proc read(order:memory_order = memory_order_seq_cst):real(64) {
      var ret: real(64);
      chpl_comm_atomic_get_real64(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:real(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_real64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      var ret:real(64);
      var v = value;
      chpl_comm_atomic_xchg_real64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:real(64), desired:real(64),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_real64(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:real(64), desired:real(64),
                                    order:memory_order = memory_order_seq_cst):bool {
      return compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:real(64), desired:real(64),
                                      order:memory_order = memory_order_seq_cst):bool {
      return compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      var v = value;
      var ret:real(64);
      chpl_comm_atomic_fetch_add_real64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:real(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_add_real64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      var v = value;
      var ret:real(64);
      chpl_comm_atomic_fetch_sub_real64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:real(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_sub_real64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      compilerError("or not defined for network atomic real");
    }
    inline proc or(value:real(64), order:memory_order = memory_order_seq_cst) {
      compilerError("or not defined for network atomic real");
    }

    inline proc fetchAnd(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      compilerError("and not defined for network atomic real");
    }
    inline proc and(value:real(64), order:memory_order = memory_order_seq_cst) {
      compilerError("and not defined for network atomic real");
    }

    inline proc fetchXor(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      compilerError("xor not defined for network atomic real");
    }
    inline proc xor(value:real(64), order:memory_order = memory_order_seq_cst) {
      compilerError("xor not defined for network atomic real");
    }

    inline proc waitFor(val:real(64), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek():real(64) {
      return _v;
    }
    inline proc poke(value:real(64)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_real64, b:ratomic_real64) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_real64, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_real64, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_real64, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_real64, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_real64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_real64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

}

pragma "atomic module"
pragma "no use ChapelStandard"
module NetworkAtomics {
  const LINENO = -1:int(32); // it'd be nice if we had something like __LINENO__

  // int(64)
  extern proc chpl_comm_atomic_get_int64(ref result:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_int64(ref desired:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_int64(ref op:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_int64(ref op:int(64),
                                               l:int(32), ref obj:int(64),
                                               ref result:int(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_int64(ref op:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_int64(ref op:int(64),
                                               l:int(32), ref obj:int(64),
                                               ref result:int(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_and_int64(ref op:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_and_int64(ref op:int(64),
                                               l:int(32), ref obj:int(64),
                                               ref result:int(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_or_int64(ref op:int(64),
                                        l:int(32), ref obj:int(64),
                                        ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_or_int64(ref op:int(64),
                                              l:int(32), ref obj:int(64),
                                              ref result:int(64),
                                              ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xor_int64(ref op:int(64),
                                         l:int(32), ref obj:int(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_xor_int64(ref op:int(64),
                                               l:int(32), ref obj:int(64),
                                               ref result:int(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_int64(ref desired:int(64),
                                          l:int(32), ref obj:int(64),
                                          ref result:int(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_int64(ref expected:int(64),
                                             ref desired:int(64),
                                             l:int(32), ref obj:int(64),
                                             ref result:bool(32),
                                             ln:int(32), fn:string);

  // int(64)
  pragma "atomic type"
  record ratomic_int64 {
    var _v: int(64);
    inline proc read(order:memory_order = memory_order_seq_cst) {
      var ret: int(64);
      chpl_comm_atomic_get_int64(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:int(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var ret:int(64);
      var v = value;
      chpl_comm_atomic_xchg_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:int(64), desired:int(64),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_int64(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:int(64), desired:int(64),
                                    order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:int(64), desired:int(64),
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_add_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      chpl_comm_atomic_add_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_sub_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      chpl_comm_atomic_sub_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_or_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc or(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      chpl_comm_atomic_or_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchAnd(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_and_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc and(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      chpl_comm_atomic_and_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchXor(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      var ret:int(64);
      chpl_comm_atomic_fetch_xor_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc xor(value:int(64), order:memory_order = memory_order_seq_cst):int(64) {
      var v = value;
      chpl_comm_atomic_xor_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc waitFor(val:int(64), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        // After waiting for the value, do a thread fence
        // in order to guarantee e.g. an acquire barrier even
        // if the on statement is not included.
        atomic_thread_fence(order);
      }
    }

    inline proc peek() {
      return _v;
    }
    inline proc poke(value:int(64)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_int64, b:ratomic_int64) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_int64, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_int64, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_int64, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_int64, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_int64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_int64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // int(32)
  extern proc chpl_comm_atomic_get_int32(ref result:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_int32(ref desired:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_int32(ref op:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_int32(ref op:int(32),
                                               l:int(32), ref obj:int(32),
                                               ref result:int(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_int32(ref op:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_int32(ref op:int(32),
                                               l:int(32), ref obj:int(32),
                                               ref result:int(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_and_int32(ref op:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_and_int32(ref op:int(32),
                                               l:int(32), ref obj:int(32),
                                               ref result:int(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_or_int32(ref op:int(32),
                                        l:int(32), ref obj:int(32),
                                        ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_or_int32(ref op:int(32),
                                              l:int(32), ref obj:int(32),
                                              ref result:int(32),
                                              ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xor_int32(ref op:int(32),
                                         l:int(32), ref obj:int(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_xor_int32(ref op:int(32),
                                               l:int(32), ref obj:int(32),
                                               ref result:int(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_int32(ref desired:int(32),
                                          l:int(32), ref obj:int(32),
                                          ref result:int(32),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_int32(ref expected:int(32),
                                             ref desired:int(32),
                                             l:int(32), ref obj:int(32),
                                             ref result:bool(32),
                                             ln:int(32), fn:string);

  // int32
  pragma "atomic type"
  record ratomic_int32 {
    var _v: int(32);
    inline proc read(order:memory_order = memory_order_seq_cst) {
      var ret: int(32);
      chpl_comm_atomic_get_int32(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:int(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var ret:int(32);
      var v = value;
      chpl_comm_atomic_xchg_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:int(32), desired:int(32),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_int32(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:int(32), desired:int(32),
                                    order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:int(32), desired:int(32),
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_add_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      chpl_comm_atomic_add_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_sub_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      chpl_comm_atomic_sub_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_or_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc or(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      chpl_comm_atomic_or_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchAnd(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_and_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc and(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      chpl_comm_atomic_and_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchXor(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      var ret:int(32);
      chpl_comm_atomic_fetch_xor_int32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc xor(value:int(32), order:memory_order = memory_order_seq_cst):int(32) {
      var v = value;
      chpl_comm_atomic_xor_int32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc waitFor(val:int(32), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek() {
      return _v;
    }
    inline proc poke(value:int(32)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_int32, b:ratomic_int32) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_int32, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_int32, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_int32, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_int32, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_int32, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_int32, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // uint(64)
  extern proc chpl_comm_atomic_get_uint64(ref result:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_uint64(ref desired:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_uint64(ref op:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_uint64(ref op:uint(64),
                                               l:int(32), ref obj:uint(64),
                                               ref result:uint(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_uint64(ref op:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_uint64(ref op:uint(64),
                                               l:int(32), ref obj:uint(64),
                                               ref result:uint(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_and_uint64(ref op:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_and_uint64(ref op:uint(64),
                                               l:int(32), ref obj:uint(64),
                                               ref result:uint(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_or_uint64(ref op:uint(64),
                                        l:int(32), ref obj:uint(64),
                                        ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_or_uint64(ref op:uint(64),
                                              l:int(32), ref obj:uint(64),
                                              ref result:uint(64),
                                              ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xor_uint64(ref op:uint(64),
                                         l:int(32), ref obj:uint(64),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_xor_uint64(ref op:uint(64),
                                               l:int(32), ref obj:uint(64),
                                               ref result:uint(64),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_uint64(ref desired:uint(64),
                                          l:int(32), ref obj:uint(64),
                                          ref result:uint(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_uint64(ref expected:uint(64),
                                             ref desired:uint(64),
                                             l:int(32), ref obj:uint(64),
                                             ref result:bool(32),
                                             ln:int(32), fn:string);

  // uint(64)
  pragma "atomic type"
  record ratomic_uint64 {
    var _v: uint(64);
    inline proc read(order:memory_order = memory_order_seq_cst) {
      var ret: uint(64);
      chpl_comm_atomic_get_uint64(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:uint(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var ret:uint(64);
      var v = value;
      chpl_comm_atomic_xchg_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:uint(64), desired:uint(64),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_uint64(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:uint(64), desired:uint(64),
                                    order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:uint(64), desired:uint(64),
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_add_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      chpl_comm_atomic_add_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_sub_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      chpl_comm_atomic_sub_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_or_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc or(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      chpl_comm_atomic_or_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchAnd(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_and_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc and(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      chpl_comm_atomic_and_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchXor(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      var ret:uint(64);
      chpl_comm_atomic_fetch_xor_uint64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc xor(value:uint(64), order:memory_order = memory_order_seq_cst):uint(64) {
      var v = value;
      chpl_comm_atomic_xor_uint64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc waitFor(val:uint(64), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek() {
      return _v;
    }
    inline proc poke(value:uint(64)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_uint64, b:ratomic_uint64) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_uint64, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_uint64, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_uint64, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_uint64, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_uint64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_uint64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // uint(32)
  extern proc chpl_comm_atomic_get_uint32(ref result:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_uint32(ref desired:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_uint32(ref op:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_uint32(ref op:uint(32),
                                               l:int(32), ref obj:uint(32),
                                               ref result:uint(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_uint32(ref op:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_uint32(ref op:uint(32),
                                               l:int(32), ref obj:uint(32),
                                               ref result:uint(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_and_uint32(ref op:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_and_uint32(ref op:uint(32),
                                               l:int(32), ref obj:uint(32),
                                               ref result:uint(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_or_uint32(ref op:uint(32),
                                        l:int(32), ref obj:uint(32),
                                        ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_or_uint32(ref op:uint(32),
                                              l:int(32), ref obj:uint(32),
                                              ref result:uint(32),
                                              ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xor_uint32(ref op:uint(32),
                                         l:int(32), ref obj:uint(32),
                                         ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_xor_uint32(ref op:uint(32),
                                               l:int(32), ref obj:uint(32),
                                               ref result:uint(32),
                                               ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_uint32(ref desired:uint(32),
                                          l:int(32), ref obj:uint(32),
                                          ref result:uint(32),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_uint32(ref expected:uint(32),
                                             ref desired:uint(32),
                                             l:int(32), ref obj:uint(32),
                                             ref result:bool(32),
                                             ln:int(32), fn:string);

  // uint(32)
  pragma "atomic type"
  record ratomic_uint32 {
    var _v: uint(32);
    inline proc read(order:memory_order = memory_order_seq_cst) {
      var ret: uint(32);
      chpl_comm_atomic_get_uint32(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:uint(32), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var ret:uint(32);
      var v = value;
      chpl_comm_atomic_xchg_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:uint(32), desired:uint(32),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_uint32(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:uint(32), desired:uint(32),
                                    order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:uint(32), desired:uint(32),
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_add_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      chpl_comm_atomic_add_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_sub_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      chpl_comm_atomic_sub_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_or_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc or(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      chpl_comm_atomic_or_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchAnd(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_and_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc and(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      chpl_comm_atomic_and_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchXor(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      var ret:uint(32);
      chpl_comm_atomic_fetch_xor_uint32(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc xor(value:uint(32), order:memory_order = memory_order_seq_cst):uint(32) {
      var v = value;
      chpl_comm_atomic_xor_uint32(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc waitFor(val:uint(32), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek() {
      return _v;
    }
    inline proc poke(value:uint(32)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_uint32, b:ratomic_uint32) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_uint32, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_uint32, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_uint32, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_uint32, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_uint32, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_uint32, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // bool, implemented with int(64)
  pragma "atomic type"
  record ratomicflag {
    var _v: int(64);
    inline proc read(order:memory_order = memory_order_seq_cst) {
      var ret: int(64);
      chpl_comm_atomic_get_int64(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret:bool;
    }
    inline proc write(value:bool, order:memory_order = memory_order_seq_cst) {
      var v = value:int(64);
      chpl_comm_atomic_put_int64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:bool, order:memory_order = memory_order_seq_cst):bool {
      var ret:int(64);
      var v = value:int(64);
      chpl_comm_atomic_xchg_int64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret:bool;
    }
    inline proc compareExchange(expected:bool, desired:bool,
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected:int(64);
      var td = desired:int(64);
      chpl_comm_atomic_cmpxchg_int64(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
inline proc compareExchangeWeak(expected:bool, desired:bool,
                                order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:bool, desired:bool,
                                      order:memory_order = memory_order_seq_cst):bool {
      return this.compareExchange(expected, desired);
    }

    inline proc testAndSet() {
      return this.exchange(true);
    }
    inline proc clear() {
      this.write(false);
    }

    inline proc waitFor(val:bool, order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek() {
      return _v;
    }
    inline proc poke(value:int(64)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomicflag, b:ratomicflag) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomicflag, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomicflag, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomicflag, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomicflag, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomicflag, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomicflag, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

  // real(64)
  extern proc chpl_comm_atomic_get_real64(ref result:real(64),
                                          l:int(32), ref obj:real(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_put_real64(ref desired:real(64),
                                          l:int(32), ref obj:real(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_add_real64(ref op:real(64),
                                          l:int(32), ref obj:real(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_add_real64(ref op:real(64),
                                                l:int(32), ref obj:real(64),
                                                ref result:real(64),
                                                ln:int(32), fn:string);
  extern proc chpl_comm_atomic_sub_real64(ref op:real(64),
                                          l:int(32), ref obj:real(64),
                                          ln:int(32), fn:string);
  extern proc chpl_comm_atomic_fetch_sub_real64(ref op:real(64),
                                                l:int(32), ref obj:real(64),
                                                ref result:real(64),
                                                ln:int(32), fn:string);
  extern proc chpl_comm_atomic_xchg_real64(ref desired:real(64),
                                           l:int(32), ref obj:real(64),
                                           ref result:real(64),
                                           ln:int(32), fn:string);
  extern proc chpl_comm_atomic_cmpxchg_real64(ref expected:real(64),
                                              ref desired:real(64),
                                              l:int(32), ref obj:real(64),
                                              ref result:bool(32),
                                              ln:int(32), fn:string);

  pragma "atomic type"
  record ratomic_real64 {
    var _v: real(64);
    inline proc read(order:memory_order = memory_order_seq_cst) {
      var ret: real(64);
      chpl_comm_atomic_get_real64(ret, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc write(value:real(64), order:memory_order = memory_order_seq_cst) {
      var v = value;
      chpl_comm_atomic_put_real64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc exchange(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      var ret:real(64);
      var v = value;
      chpl_comm_atomic_xchg_real64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchange(expected:real(64), desired:real(64),
                                order:memory_order = memory_order_seq_cst):bool {
      var ret:bool(32);
      var te = expected;
      var td = desired;
      chpl_comm_atomic_cmpxchg_real64(te, td, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc compareExchangeWeak(expected:real(64), desired:real(64),
                                    order:memory_order = memory_order_seq_cst):bool {
      return compareExchange(expected, desired);
    }
    inline proc compareExchangeStrong(expected:real(64), desired:real(64),
                                      order:memory_order = memory_order_seq_cst):bool {
      return compareExchange(expected, desired);
    }

    inline proc fetchAdd(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      var v = value;
      var ret:real(64);
      chpl_comm_atomic_fetch_add_real64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc add(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      var v = value;
      chpl_comm_atomic_add_real64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchSub(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      var v = value;
      var ret:real(64);
      chpl_comm_atomic_fetch_sub_real64(v, this.locale.id:int(32), this._v, ret, LINENO, "NetworkAtomics.chpl");
      return ret;
    }
    inline proc sub(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      var v = value;
      chpl_comm_atomic_sub_real64(v, this.locale.id:int(32), this._v, LINENO, "NetworkAtomics.chpl");
    }

    inline proc fetchOr(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      compilerError("or not defined for network atomic real");
    }
    inline proc or(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      compilerError("or not defined for network atomic real");
    }

    inline proc fetchAnd(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      compilerError("and not defined for network atomic real");
    }
    inline proc and(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      compilerError("and not defined for network atomic real");
    }

    inline proc fetchXor(value:real(64), order:memory_order = memory_order_seq_cst):real(64) {
      compilerError("xor not defined for network atomic real");
    }
    inline proc xor(value:real(64), order:memory_order = memory_order_seq_cst) {
      compilerError("xor not defined for network atomic real");
    }

    inline proc waitFor(val:real(64), order:memory_order = memory_order_seq_cst) {
      on this {
        while (read(memory_order_relaxed) != val) do chpl_task_yield();
        atomic_thread_fence(order);
      }
    }

    inline proc peek() {
      return _v;
    }
    inline proc poke(value:real(64)) {
      _v = value;
    }

    proc writeThis(x: Writer) {
      x.write(read());
    }
  }

  inline proc =(ref a:ratomic_real64, b:ratomic_real64) {
    a.write(b.read());
  }
  inline proc =(ref a:ratomic_real64, b) {
    compilerError("Cannot directly assign network atomic variables");
  }
  inline proc +(a:ratomic_real64, b) {
    compilerError("Cannot directly add network atomic variables");
    return a;
  }
  inline proc -(a:ratomic_real64, b) {
    compilerError("Cannot directly subtract network atomic variables");
    return a;
  }
  inline proc *(a:ratomic_real64, b) {
    compilerError("Cannot directly multiply network atomic variables");
    return a;
  }
  inline proc /(a:ratomic_real64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }
  inline proc %(a:ratomic_real64, b) {
    compilerError("Cannot directly divide network atomic variables");
    return a;
  }

}


Removed all format() calls satisfactorily

//
// This test is pulled from intern ii02 in the codes written in the
// Summer of 2011 to measure increase in productivity using Chapel
// versus C/MPI.It is a pared down version of the Locally Self-consistent
// Multiple Scattering (LSMS) application.
//

use Time;

config const debug = false;
config const reportFrequency = 1025;
config const perfTest = false;
config const displayLIZ = false;

config const span = 5;

const span_x = span,
	  span_y = span,
	  span_z = span,
	  nAtoms = span_x * span_y * span_z,
	  spanT  = (span, span, span);

config
const atomSpacing = 5.000, //spacing in X, Y, and Z
	  lizRadius   = 7.110, //radius of LIZ sphere
	  nIterations = 1024;

const reductionFactor = 1000.0;

param nExtent = 13;
type AtomMatrix = nExtent*real;
//type AtomMatrix = [0..#nExtent] real;

const GridDom  = {0..#span_x, 0..#span_y, 0..#span_z};

proc main() {
	var t: Timer;

	writeln("[[ LSMS ]]");
	writeln("Problem size = [", span_x, ", ", span_y, ", ", span_z, "]");

	//calculate Local Interaction Zones
	var lizDoms: [GridDom] sparse subdomain(GridDom);
	for (a, liz) in zip(GridDom, lizDoms) {
		for ac in GridDom do if a != ac {
			//compute dist between 2 points
			var diff: 3*int;
			for param d in 1..3 do diff[d] = circularDistance(a[d], ac[d], spanT[d]);
			var dist = atomSpacing * sqrt(diff[1]**2 + diff[2]**2 + diff[3]**2);
			if dist <= lizRadius {
				liz += ac;
			}
		}
	}
	if displayLIZ then writeln("LIZ counts: ", [liz in lizDoms] liz.numIndices);

	//initialize atoms
	var atoms: [GridDom] AtomMatrix;
	for (i, atom) in zip(GridDom, atoms) {
		for param e in 1..nExtent do atom[e] = GridDom.indexOrder(i);
	}

	t.start();

	for itr in 0..#nIterations {
		if itr % reportFrequency == 0 && reportFrequency <= nIterations {
			writef("step  ###...\n", itr);
		}

		//each atom adds up extent values from neighbors (members of its liz sphere)
		var totals: [GridDom] AtomMatrix;
		for (liz, total, i) in zip(lizDoms, totals, GridDom) {
			for ac in liz {
				total += atoms[ac];
			}
		}
		for a in GridDom {
			for param e in 1..nExtent {
				atoms[a][e] += totals[a][e] / reductionFactor;
			}
		}

		if itr == 0 || itr == nIterations-1 {
			checkExpected(itr, atoms);
		}
	}

	t.stop();

	writeln("Success!");

	if perfTest then writeln("Chapel serial time = ", t.elapsed(), " s");
}

proc checkExpected(itr: int, atoms: [GridDom] AtomMatrix) {
	if span != 5 || nIterations != 1024 {
		writeln("Expected value check disabled...");
		return;
	}
	const first = GridDom.low,
		  last  = GridDom.high;

	var ExpectedDom: sparse subdomain(GridDom);
	ExpectedDom += first; ExpectedDom += last;

	var expectedValues: [ExpectedDom] real;
	if itr == 0 {
		expectedValues[first] = 0.775;
		expectedValues[last]  = 125.5;
	} else {
		expectedValues[first] = 5320018409.9;
		expectedValues[last]  = 5324998555.3;
	}

	for i in ExpectedDom {
		var tolerance = max(expectedValues[i] * 1e-9, 0.1);
		var pass = true;
		for param e in 1..nExtent {
			if abs(atoms[i][e] - expectedValues[i]) > tolerance then pass = false;
		}
                if debug { writef("itr %4n @ %t: %12.9r ~=~ %12.9r\n",
                                  itr, i, atoms[i][1], expectedValues[i]); }
		if !pass {
			writeln("Computed values do not match expected values: itr = ", itr,
					" @ ", i, ": ", atoms[i][1], " != ", expectedValues[i]);
			exit(0);
		}
	}
}

proc circularDistance(a, b, size: int) {
	if a < b {
		return min(a+size-b, b-a);
	} else {
		return min(a-b, b-a+size);
	}
}

//
// This test is pulled from intern ii02 in the codes written in the
// Summer of 2011 to measure increase in productivity using Chapel
// versus C/MPI.It is a pared down version of the Locally Self-consistent
// Multiple Scattering (LSMS) application.
//

use Time;

config const debug = false;
config const reportFrequency = 1025;
config const perfTest = false;
config const displayLIZ = false;

config const span = 5;

const span_x = span,
	  span_y = span,
	  span_z = span,
	  nAtoms = span_x * span_y * span_z,
	  spanT  = (span, span, span);

config
const atomSpacing = 5.000, //spacing in X, Y, and Z
	  lizRadius   = 7.110, //radius of LIZ sphere
	  nIterations = 1024;

const reductionFactor = 1000.0;

param nExtent = 13;
type AtomMatrix = nExtent*real;
//type AtomMatrix = [0..#nExtent] real;

const GridDom  = {0..#span_x, 0..#span_y, 0..#span_z};

proc main() {
	var t: Timer;

	writeln("[[ LSMS ]]");
	writeln("Problem size = [", span_x, ", ", span_y, ", ", span_z, "]");

	//calculate Local Interaction Zones
	var lizDoms: [GridDom] sparse subdomain(GridDom);
	for (a, liz) in zip(GridDom, lizDoms) {
		for ac in GridDom do if a != ac {
			//compute dist between 2 points
			var diff: 3*int;
			for param d in 1..3 do diff[d] = circularDistance(a[d], ac[d], spanT[d]);
			var dist = atomSpacing * sqrt(diff[1]**2 + diff[2]**2 + diff[3]**2);
			if dist <= lizRadius {
				liz += ac;
			}
		}
	}
	if displayLIZ then writeln("LIZ counts: ", [liz in lizDoms] liz.numIndices);

	//initialize atoms
	var atoms: [GridDom] AtomMatrix;
	for (i, atom) in zip(GridDom, atoms) {
		for param e in 1..nExtent do atom[e] = GridDom.indexOrder(i);
	}

	t.start();

	for itr in 0..#nIterations {
		if itr % reportFrequency == 0 && reportFrequency <= nIterations {
			writef("step####...\n", itr);
		}

		//each atom adds up extent values from neighbors (members of its liz sphere)
		var totals: [GridDom] AtomMatrix;
		for (liz, total, i) in zip(lizDoms, totals, GridDom) {
			for ac in liz {
				total += atoms[ac];
			}
		}
		for a in GridDom {
			for param e in 1..nExtent {
				atoms[a][e] += totals[a][e] / reductionFactor;
			}
		}

		if itr == 0 || itr == nIterations-1 {
			checkExpected(itr, atoms);
		}
	}

	t.stop();

	writeln("Success!");

	if perfTest then writeln("Chapel serial time = ", t.elapsed(), " s");
}

proc checkExpected(itr: int, atoms: [GridDom] AtomMatrix) {
	if span != 5 || nIterations != 1024 {
		writeln("Expected value check disabled...");
		return;
	}
	const first = GridDom.low,
		  last  = GridDom.high;

	var ExpectedDom: sparse subdomain(GridDom);
	ExpectedDom += first; ExpectedDom += last;

	var expectedValues: [ExpectedDom] real;
	if itr == 0 {
		expectedValues[first] = 0.775;
		expectedValues[last]  = 125.5;
	} else {
		expectedValues[first] = 5320018409.9;
		expectedValues[last]  = 5324998555.3;
	}

	for i in ExpectedDom {
		var tolerance = max(expectedValues[i] * 1e-9, 0.1);
		var pass = true;
		for param e in 1..nExtent {
			if abs(atoms[i][e] - expectedValues[i]) > tolerance then pass = false;
		}
		if debug { writeln("itr ", format("%4d",itr), " @ ", i, ": ",
				           format("%12.9g",atoms[i][1]), " ~=~ ",
						   format("%12.9g",expectedValues[i])); }
		if !pass {
			writeln("Computed values do not match expected values: itr = ", itr,
					" @ ", i, ": ", atoms[i][1], " != ", expectedValues[i]);
			exit(0);
		}
	}
}

proc circularDistance(a, b, size: int) {
	if a < b {
		return min(a+size-b, b-a);
	} else {
		return min(a-b, b-a+size);
	}
}


Fixed the --no-local regression in leadFollowOpt.chpl

This test operates "naked" BlockDom objects, so some things
that would happen when using a Block-distributed domain
do not happen here. In particular, (a) reference counting
and (b) looking up in the privatized-class table.

(a) was already compensated for before string-as-rec.

(b) was not exposed before string-as-rec. However,
even before string-as-rec, if we added this line to the test:

  _isPrivatized(D1);

we would get the same crashing behavior, due to a lookup
in the privatized-class table with pid == -1.

pid == -1 is because "naked" BlockDom objects are not privatized
implicitly. So the solution is to privatize them explicitly,
just like the correction already in place for (a).

The lookup happens due to re-privatization of iterator fields
aka reprivatizeIterators(), introduced in 6ea8a445 aka r15209.
The iterator class in question is due to this loop:
  forall (i,j) in zip(D1, D2) do

Before string-as-rec the compiler did not label BlockDom
with FLAG_PRIVATIZED_CLASS. That's because _isPrivatized()
was not invoked on any BlockDom instances.

string-as-rec adds autoCopy/autoDestroy on BlockDom
that invokes _isPrivatized() on BlockDom.
So the compiler labels BlockDom with FLAG_PRIVATIZED_CLASS
and applies re-privatization to the BlockDom field
of the iterator class. This results in a lookup with pid==-1.

use BlockDist;

var Dist = new dmap(new Block(boundingBox={1..9}));

var D1 = Dist.newRectangularDom(1, int(64), false);
var D2 = Dist.newRectangularDom(1, int(64), false);
D1.dsiSetIndices({1..9});
D2.dsiSetIndices({2..10});

// Parallel iteration over "nude" domains is dangerous.
// This is the other way to avoid the problem.
D1.incRefCount();
D2.incRefCount();
_newPrivatizedClass(D1);
_newPrivatizedClass(D2);

forall (i,j) in zip(D1, D2) do
  writeln("(i,j) is: ", (i,j));

var cnt2 = D2.decRefCount();
if cnt2 == 0 then
  delete D2;

var cnt1 = D1.decRefCount();
if cnt1 == 0 then
  delete D1;

use BlockDist;

var Dist = new dmap(new Block(boundingBox={1..9}));

var D1 = Dist.newRectangularDom(1, int(64), false);
var D2 = Dist.newRectangularDom(1, int(64), false);
D1.dsiSetIndices({1..9});
D2.dsiSetIndices({2..10});

// Parallel iteration over "nude" domains is dangerous.
// This is the other way to avoid the problem.
D1.incRefCount();
D2.incRefCount();

forall (i,j) in zip(D1, D2) do
  writeln("(i,j) is: ", (i,j));

var cnt2 = D2.decRefCount();
if cnt2 == 0 then
  delete D2;

var cnt1 = D1.decRefCount();
if cnt1 == 0 then
  delete D1;