Mapping Chapel's atomics to gnu intrinsics for xlc should be relatively 
straightforward since we already use them for gnu, and I have a BG account 
thru Jeff so could potentially take on this work after Thanksgiving if it 
would help someone.

-Brad


On Wed, 20 Nov 2013, Jeff Hammond wrote:

> As far as an implementation of atomics on PPC goes, I recommend starting 
> with GCC intrinsics, as these are also supported by IBM XLC. Leave 
> inline assembly as an possible optimization later. I doubt it is worth 
> the extra effort in most cases.
>
> If someone wants to work on this, I can try to help with testing and 
> such. I have access to both Blue Gene and POWER7 systems right now. I 
> may be able to arrange access for Chapel developers if that is critical.
>
> Jeff
>
> Sent from my iPhone
>
>> On Nov 20, 2013, at 8:57 AM, "Michael P. Ferguson" <[email protected]> 
>> wrote:
>>
>> Hi Jason -
>>
>> Can you explain why the existing atomics interface in
>> Atomics.chpl is not sufficient?
>>
>> Then, assuming you need some different functionality, why not extend
>> the existing atomics implementation instead of creating a completely
>> new one? The existing implementation defines functions like
>>  atomic_fetch_add_explicit_uint_least64
>> in runtime/include/atomics/*/chpl-atomics.h
>>
>> For example, to create XLC style Power intrinsics, it would make sense
>> to add a new directory there with a different .h file.
>>
>> You can call these C functions directly from Chapel, although I could
>> believe that you need to change something to get them to do what you
>> want. The Atomics module mostly adds an 'on' statement around these calls.
>>
>> Cheers,
>>
>> -michael
>>
>> ________________________________________
>> From: Jason Riedy [[email protected]]
>> Sent: Tuesday, November 19, 2013 18:50
>> To: [email protected]
>> Subject: Atomic-intrinsics.chpl sanity check
>>
>> [this is a bit of a follow-up to in-person interactions at SC13,
>> but posting it here for a wider audience (aka not pestering Brad
>> *again*)...]
>>
>> Does the following seem like a half-way sane method for adapting
>> to different compilers' intrinsics in Chapel?  There's heavy
>> cheating around the ll/sc, and I don't have a Power account handy
>> for testing, so consider this a sketch...
>>
>>
>> // module Atomic-intrinsics.chpl
>> use Atomics;
>>
>> module impl {
>>  use ChapelBase;
>>  // XXX: Don't recall if pgi implements these...
>>  inline proc gccish_intrinsics() param {
>>    return CHPL_TARGET_COMPILER == "gnu" || CHPL_TARGET_COMPILER == "intel" ||
>>      CHPL_TARGET_COMPILER == "pgi" || CHPL_TARGET_COMPILER == 
>> "cray-prgenv-gnu" ||
>>      CHPL_TARGET_COMPILER == "cray-prgenv-intel" ||
>>      CHPL_TARGET_COMPILER == "cray-prgenv-pgi";
>>  }
>>  // XXX: This should be for xlc on power and not other platforms.
>>  inline proc xlcish_power_intrinsics() param {
>>    return CHPL_TARGET_COMPILER == "xlc";
>>  }
>>  inline proc xmtish_intrinsics() param {
>>    compilerError("Get a real machine.");
>>    return false;
>>  }
>>  inline proc target_compiler_name() param { return CHPL_TARGET_COMPILER; }
>> }
>> use impl;
>>
>>
>> // local{} clauses just to make sure...
>>
>> // OP: add
>>
>> inline proc atomic_fetch_add(ref x, val: x.type, const 
>> order:memory_order=memory_order_seq_cst) : x.type {
>>  if (gccish_intrinsics()) {
>>    extern proc __atomic_fetch_add(ref x: real(64), val: real(64), 
>> order:memory_order) : real(64);
>>    extern proc __atomic_fetch_add(ref x: int(64), val: int(64), 
>> order:memory_order) : int(64);
>>    extern proc __atomic_fetch_add(ref x: uint(64), val: uint(64), 
>> order:memory_order) : uint(64);
>>    extern proc __atomic_fetch_add(ref x: real(32), val: real(32), 
>> order:memory_order) : real(32);
>>    extern proc __atomic_fetch_add(ref x: int(32), val: int(32), 
>> order:memory_order) : int(32);
>>    extern proc __atomic_fetch_add(ref x: uint(32), val: uint(32), 
>> order:memory_order) : uint(32);
>>    extern proc __atomic_fetch_add(ref x: int(16), val: int(16), 
>> order:memory_order) : int(16);
>>    extern proc __atomic_fetch_add(ref x: uint(16), val: uint(16), 
>> order:memory_order) : uint(16);
>>    extern proc __atomic_fetch_add(ref x: int(8), val: int(8), 
>> order:memory_order) : int(8);
>>    extern proc __atomic_fetch_add(ref x: uint(8), val: uint(8), 
>> order:memory_order) : uint(8);
>>    inline proc __atomic_fetch_add(x, val, order) {
>>      compilerError("No fetch and add for this type.");
>>      return 0:x.type;
>>    }
>>
>>    var retval : x.type;
>>    local {
>>      retval = __atomic_fetch_add(x, val, order);
>>    }
>>    return retval;
>>  } else if (xlcish_power_intrinsics()) {
>>    compilerWarning("Completely untested atomics for ", 
>> target_compiler_name());
>>    compilerWarning("  Needs isync, eieio, etc. for memory order.");
>>    var retval : x.type;
>>    inline proc __fa(ref x: int(32), in val: int(32)) {
>>      extern proc __fetch_and_add(ref x: int(32), in val: int(32)) : int(32);
>>      return __fetch_and_add(x, val);
>>    }
>>    inline proc __fa(ref x: int(64), in val: int(64)) {
>>      extern proc __fetch_and_addlp(ref x: int(64), in val: int(64)) : 
>> int(64);
>>      return __fetch_and_addlp(x, val);
>>    }
>>    inline proc __fa(ref x: real(32), in val: real(32)) {
>>      extern proc __lwarx(ref x: real(32)) : real(32);
>>      extern proc __stwcx(ref x: real(32), in val: real(32)) : int(32);
>>      var outval : real(32);
>>      var newval : real(32);
>>      do {
>>        outval = __lwarx(x);
>>        newval = outval + val;
>>      } while !(__stwcx (x, newval));
>>      return outval;
>>    }
>>    inline proc __fa(ref x: real(64), in val: real(64)) {
>>      extern proc __ldarx(ref x: real(64)) : real(64);
>>      extern proc __stdcx(ref x: real(64), in val: real(64)) : int(64);
>>      var outval : real(64);
>>      var newval : real(64);
>>      do {
>>        outval = __ldarx(x);
>>        newval = outval + val;
>>      } while !(__stdcx (x, newval));
>>      return outval;
>>    }
>>    inline proc __fa(x, val) {
>>      compilerError("No fetch and add for this type.");
>>    }
>>    local {
>>      retval = __fa(x, val);
>>    }
>>    return retval;
>>  } else {
>>    compilerError("Unrecognized target compiler: ", target_compiler_name());
>>  }
>> }
>>
>> inline proc atomic_add_fetch(ref x, val: x.type, const 
>> order:memory_order=memory_order_seq_cst) : x.type {
>>  if (gccish_intrinsics()) {
>>    extern proc __atomic_add_fetch(ref x: real(64), val: real(64), 
>> order:memory_order) : real(64);
>>    extern proc __atomic_add_fetch(ref x: int(64), val: int(64), 
>> order:memory_order) : int(64);
>>    extern proc __atomic_add_fetch(ref x: uint(64), val: uint(64), 
>> order:memory_order) : uint(64);
>>    extern proc __atomic_add_fetch(ref x: real(32), val: real(32), 
>> order:memory_order) : real(32);
>>    extern proc __atomic_add_fetch(ref x: int(32), val: int(32), 
>> order:memory_order) : int(32);
>>    extern proc __atomic_add_fetch(ref x: uint(32), val: uint(32), 
>> order:memory_order) : uint(32);
>>    extern proc __atomic_add_fetch(ref x: int(16), val: int(16), 
>> order:memory_order) : int(16);
>>    extern proc __atomic_add_fetch(ref x: uint(16), val: uint(16), 
>> order:memory_order) : uint(16);
>>    extern proc __atomic_add_fetch(ref x: int(8), val: int(8), 
>> order:memory_order) : int(8);
>>    extern proc __atomic_add_fetch(ref x: uint(8), val: uint(8), 
>> order:memory_order) : uint(8);
>>    inline proc __atomic_add_fetch(x, val, order) {
>>      compilerError("No fetch and add for this type.");
>>      return 0:x.type;
>>    }
>>
>>    var retval : x.type;
>>    local {
>>      retval = __atomic_add_fetch(x, val, order);
>>    }
>>    return retval;
>>  } else if (xlcish_power_intrinsics()) {
>>    compilerWarning("Completely untested atomics for ", 
>> target_compiler_name());
>>    compilerWarning("  Needs isync, eieio, etc. for memory order.");
>>    var retval : x.type;
>>    inline proc __fa(ref x: int(32), in val: int(32)) {
>>      extern proc __fetch_and_add(ref x: int(32), in val: int(32)) : int(32);
>>      return __fetch_and_add(x, val) + val;
>>    }
>>    inline proc __fa(ref x: int(64), in val: int(64)) {
>>      extern proc __fetch_and_addlp(ref x: int(64), in val: int(64)) : 
>> int(64);
>>      return __fetch_and_addlp(x, val) + val;
>>    }
>>    inline proc __fa(ref x: real(32), in val: real(32)) {
>>      extern proc __lwarx(ref x: real(32)) : real(32);
>>      extern proc __stwcx(ref x: real(32), in val: real(32)) : int(32);
>>      var outval : real(32);
>>      var newval : real(32);
>>      do {
>>        outval = __lwarx(x);
>>        newval = outval + val;
>>      } while !(__stwcx (x, newval));
>>      return newval;
>>    }
>>    inline proc __fa(ref x: real(64), in val: real(64)) {
>>      extern proc __ldarx(ref x: real(64)) : real(64);
>>      extern proc __stdcx(ref x: real(64), in val: real(64)) : int(64);
>>      var outval : real(64);
>>      var newval : real(64);
>>      do {
>>        outval = __ldarx(x);
>>        newval = outval + val;
>>      } while !(__stdcx (x, newval));
>>      return newval;
>>    }
>>    inline proc __fa(x, val) {
>>      compilerError("No fetch and add for this type.");
>>    }
>>    local {
>>      retval = __fa(x, val);
>>    }
>>    return retval;
>>  } else {
>>    compilerError("Unrecognized target compiler: ", target_compiler_name());
>>  }
>> }
>>
>>
>> inline proc atomic_add(ref x, val: x.type, const 
>> order:memory_order=memory_order_seq_cst) : x.type {
>>  // Sufficient.
>>  return atomic_fetch_add(x, val, order);
>> }
>>
>> --
>> Jason Riedy
>>
>>
>> ------------------------------------------------------------------------------
>> Shape the Mobile Experience: Free Subscription
>> Software experts and developers: Be at the forefront of tech innovation.
>> Intel(R) Software Adrenaline delivers strategic insight and game-changing
>> conversations that shape the rapidly evolving mobile landscape. Sign up now.
>> http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
>> _______________________________________________
>> Chapel-users mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/chapel-users
>>
>> ------------------------------------------------------------------------------
>> Shape the Mobile Experience: Free Subscription
>> Software experts and developers: Be at the forefront of tech innovation.
>> Intel(R) Software Adrenaline delivers strategic insight and game-changing
>> conversations that shape the rapidly evolving mobile landscape. Sign up now.
>> http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
>> _______________________________________________
>> Chapel-users mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/chapel-users
>
> ------------------------------------------------------------------------------
> Shape the Mobile Experience: Free Subscription
> Software experts and developers: Be at the forefront of tech innovation.
> Intel(R) Software Adrenaline delivers strategic insight and game-changing
> conversations that shape the rapidly evolving mobile landscape. Sign up now.
> http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
> _______________________________________________
> Chapel-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/chapel-users
>

------------------------------------------------------------------------------
Shape the Mobile Experience: Free Subscription
Software experts and developers: Be at the forefront of tech innovation.
Intel(R) Software Adrenaline delivers strategic insight and game-changing 
conversations that shape the rapidly evolving mobile landscape. Sign up now. 
http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users

Reply via email to