@@ -836,154 +836,122 @@ wrong queue is used as an argument in any of the member functions of the
836
836
#### Atomic Operations
837
837
838
838
SYCLcompat provides an interface for common atomic operations (` add ` , ` sub ` ,
839
- ` and ` , ` or ` , ` xor ` , ` min ` , ` max ` , ` exchange ` , ` compare_exchange ` ). While SYCL
840
- exposes atomic operations through member functions of ` sycl::atomic_ref ` , this
841
- library provides access via functions taking a standard pointer argument.
842
- Template arguments control the ` sycl::memory_scope ` , ` sycl::memory_order ` and
843
- ` sycl::access::address_space ` of these atomic operations. SYCLcompat also
844
- exposes overloads for these atomic functions which take a runtime memoryScope
845
- argument. Every atomic operation is implemented via an API function taking a raw
846
- pointer as the target. Additional overloads for
839
+ ` and ` , ` or ` , ` xor ` , ` min ` , ` max ` , ` inc ` , ` dec ` , ` exchange ` , ` compare_exchange ` ).
840
+ While SYCL exposes atomic operations through member functions of
841
+ ` sycl::atomic_ref ` , this library provides access via functions taking a standard
842
+ pointer argument. Template arguments control the ` sycl::memory_scope ` ,
843
+ ` sycl::memory_order ` and ` sycl:: access::address_space` of these atomic
844
+ operations. SYCLcompat also exposes overloads for these atomic functions which
845
+ take a runtime memoryScope argument. Every atomic operation is implemented via
846
+ an API function taking a raw pointer as the target. Additional overloads for
847
847
` syclcompat::compare_exchange_strong ` are provided which take a
848
- ` sycl::multi_ptr ` instead of a raw pointer. Addition and subtraction make use of
849
- ` arith_t ` to differentiate between numeric and pointer arithmetics.
848
+ ` sycl::multi_ptr ` instead of a raw pointer. The type of the operand for most
849
+ atomic operations is defined as ` syclcompat::type_identity_t<T> ` to avoid
850
+ template deduction issues when an operand of a different type (e.g. double
851
+ literal) is supplied. Atomic addition and subtraction free functions make use of
852
+ ` syclcompat::arith_t<T> ` to differentiate between numeric and pointer
853
+ arithmetics.
850
854
851
855
The available operations are exposed as follows:
852
856
853
857
``` c++
854
858
namespace syclcompat {
855
859
860
+ template <class T > struct type_identity {
861
+ using type = T;
862
+ };
863
+ template <class T > using type_identity_t = typename type_identity<T >::type;
864
+
856
865
template <typename T > struct arith {
857
866
using type = std::conditional_t< std::is_pointer_v<T > , std::ptrdiff_t, T>;
858
867
};
859
868
template <typename T > using arith_t = typename arith<T >::type;
860
869
861
- template <typename T,
862
- sycl::access::address_space addressSpace =
863
- sycl::access::address_space::global_space,
870
+ template <sycl::access::address_space addressSpace =
871
+ sycl::access::address_space::generic_space,
864
872
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
865
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
873
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
874
+ typename T>
866
875
T atomic_fetch_add(T * addr, arith_t<T > operand);
867
- template <typename T,
868
- sycl::access::address_space addressSpace =
869
- sycl::access::address_space::global_space,
870
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
871
- T atomic_fetch_add(T * addr, arith_t<T > operand,
872
- sycl::memory_order memoryOrder);
873
876
874
- template <typename T,
875
- sycl::access::address_space addressSpace =
876
- sycl::access::address_space::global_space,
877
+ template <sycl::access::address_space addressSpace =
878
+ sycl::access::address_space::generic_space,
877
879
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
878
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
880
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
881
+ typename T>
879
882
T atomic_fetch_sub(T * addr, arith_t<T > operand);
880
- template <typename T,
881
- sycl::access::address_space addressSpace =
882
- sycl::access::address_space::global_space,
883
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
884
- T atomic_fetch_sub(T * addr, arith_t<T > operand,
885
- sycl::memory_order memoryOrder);
886
883
887
- template <typename T,
888
- sycl::access::address_space addressSpace =
889
- sycl::access::address_space::global_space,
884
+ template <sycl::access::address_space addressSpace =
885
+ sycl::access::address_space::generic_space,
890
886
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
891
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
892
- T atomic_fetch_and(T * addr, T operand);
893
- template <typename T,
894
- sycl::access::address_space addressSpace =
895
- sycl::access::address_space::global_space,
896
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
897
- T atomic_fetch_and(T * addr, T operand, sycl::memory_order memoryOrder);
887
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
888
+ typename T>
889
+ T atomic_fetch_and(T * addr, type_identity<T > operand);
898
890
899
- template <typename T,
900
- sycl::access::address_space addressSpace =
901
- sycl::access::address_space::global_space,
891
+ template <sycl::access::address_space addressSpace =
892
+ sycl::access::address_space::generic_space,
902
893
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
903
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
904
- T atomic_fetch_or(T * addr, T operand);
905
- template <typename T,
906
- sycl::access::address_space addressSpace =
907
- sycl::access::address_space::global_space,
908
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
909
- T atomic_fetch_or(T * addr, T operand, sycl::memory_order memoryOrder);
894
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
895
+ typename T>
896
+ T atomic_fetch_or(T * addr, type_identity<T > operand);
910
897
911
- template <typename T,
912
- sycl::access::address_space addressSpace =
913
- sycl::access::address_space::global_space,
898
+ template <sycl::access::address_space addressSpace =
899
+ sycl::access::address_space::generic_space,
914
900
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
915
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
916
- T atomic_fetch_xor(T * addr, T operand);
917
- template <typename T,
918
- sycl::access::address_space addressSpace =
919
- sycl::access::address_space::global_space,
920
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
921
- T atomic_fetch_xor(T * addr, T operand, sycl::memory_order memoryOrder);
901
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
902
+ typename T>
903
+ T atomic_fetch_xor(T * addr, type_identity<T > operand);
922
904
923
- template <typename T,
924
- sycl::access::address_space addressSpace =
925
- sycl::access::address_space::global_space,
905
+ template <sycl::access::address_space addressSpace =
906
+ sycl::access::address_space::generic_space,
926
907
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
927
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
928
- T atomic_fetch_min(T * addr, T operand);
929
- template <typename T,
930
- sycl::access::address_space addressSpace =
931
- sycl::access::address_space::global_space,
932
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
933
- T atomic_fetch_min(T * addr, T operand, sycl::memory_order memoryOrder);
908
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
909
+ typename T>
910
+ T atomic_fetch_min(T * addr, type_identity<T > operand);
934
911
935
- template <typename T,
936
- sycl::access::address_space addressSpace =
937
- sycl::access::address_space::global_space,
912
+ template <sycl::access::address_space addressSpace =
913
+ sycl::access::address_space::generic_space,
938
914
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
939
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
940
- T atomic_fetch_max(T * addr, T operand);
941
- template <typename T,
942
- sycl::access::address_space addressSpace =
943
- sycl::access::address_space::global_space,
944
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
945
- T atomic_fetch_max(T * addr, T operand, sycl::memory_order memoryOrder);
915
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
916
+ typename T>
917
+ T atomic_fetch_max(T * addr, type_identity<T > operand);
946
918
947
919
template <sycl::access::address_space addressSpace =
948
- sycl::access::address_space::global_space ,
920
+ sycl::access::address_space::generic_space ,
949
921
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
950
922
sycl::memory_scope memoryScope = sycl::memory_scope::device>
951
923
unsigned int atomic_fetch_compare_inc(unsigned int * addr,
952
924
unsigned int operand);
925
+
953
926
template <sycl::access::address_space addressSpace =
954
- sycl::access::address_space::global_space,
927
+ sycl::access::address_space::generic_space,
928
+ sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
955
929
sycl::memory_scope memoryScope = sycl::memory_scope::device>
956
- unsigned int atomic_fetch_compare_inc(unsigned int * addr,
957
- unsigned int operand,
958
- sycl::memory_order memoryOrder);
930
+ unsigned int atomic_fetch_compare_dec(unsigned int * addr,
931
+ unsigned int operand);
959
932
960
- template <typename T,
961
- sycl::access::address_space addressSpace =
962
- sycl::access::address_space::global_space,
933
+ template <sycl::access::address_space addressSpace =
934
+ sycl::access::address_space::generic_space,
963
935
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
964
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
965
- T atomic_exchange(T * addr, T operand);
966
- template <typename T,
967
- sycl::access::address_space addressSpace =
968
- sycl::access::address_space::global_space,
969
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
970
- T atomic_exchange(T * addr, T operand, sycl::memory_order memoryOrder);
936
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
937
+ typename T>
938
+ T atomic_exchange(T * addr, type_identity<T > operand);
971
939
972
- template <typename T,
973
- sycl::access::address_space addressSpace =
974
- sycl::access::address_space::global_space,
940
+ template <sycl::access::address_space addressSpace =
941
+ sycl::access::address_space::generic_space,
975
942
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
976
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
943
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
944
+ typename T>
977
945
T atomic_compare_exchange_strong(
978
- sycl::multi_ptr<T, sycl::access::address_space::global_space > addr,
946
+ sycl::multi_ptr<T, sycl::access::address_space::generic_space > addr,
979
947
T expected, T desired,
980
948
sycl::memory_order success = sycl::memory_order::relaxed,
981
949
sycl::memory_order fail = sycl::memory_order::relaxed);
982
- template <typename T,
983
- sycl::access::address_space addressSpace =
984
- sycl::access::address_space::global_space,
950
+ template <sycl::access::address_space addressSpace =
951
+ sycl::access::address_space::generic_space,
985
952
sycl::memory_order memoryOrder = sycl::memory_order::relaxed,
986
- sycl::memory_scope memoryScope = sycl::memory_scope::device>
953
+ sycl::memory_scope memoryScope = sycl::memory_scope::device,
954
+ typename T>
987
955
T atomic_compare_exchange_strong(
988
956
T * addr, T expected, T desired,
989
957
sycl::memory_order success = sycl::memory_order::relaxed,
0 commit comments