@@ -1442,8 +1442,10 @@ class CBasicTestFetchAddSpecialFloats
14421442 // threads to be mapped deterministically onto the input data array.
14431443 // This enables repeated add operations arranged so that every
14441444 // special value is added to every other one (“all-to-all”).
1445-
1446- if constexpr (std::is_same_v<HostDataType, HOST_FLOAT>)
1445+ if constexpr (
1446+ std::is_same_v<
1447+ HostDataType,
1448+ HOST_DOUBLE> || std::is_same_v<HostDataType, HOST_FLOAT>)
14471449 {
14481450 auto spec_vals = GetSpecialValues ();
14491451 StartValue (spec_vals.size ());
@@ -1452,7 +1454,6 @@ class CBasicTestFetchAddSpecialFloats
14521454 }
14531455 else if constexpr (std::is_same_v<HostDataType, HOST_HALF>)
14541456 {
1455-
14561457 auto spec_vals = GetSpecialValues ();
14571458 StartValue (cl_half_from_float (spec_vals.size (), gHalfRoundingMode ));
14581459 CBasicTestMemOrderScope<HostAtomicType,
@@ -1462,14 +1463,21 @@ class CBasicTestFetchAddSpecialFloats
14621463
14631464 static std::vector<HostDataType> &GetSpecialValues ()
14641465 {
1465- const float test_value_zero = 0 .0f ;
1466- const float test_value_minus_zero = -0 .0f ;
1467- const float test_value_without_fraction = 2 .0f ;
1468- const float test_value_with_fraction = 2 .2f ;
1469-
14701466 static std::vector<HostDataType> special_values;
1471- if constexpr (std::is_same_v<HostDataType, HOST_FLOAT>)
1467+ if constexpr (
1468+ std::is_same_v<
1469+ HostDataType,
1470+ HOST_DOUBLE> || std::is_same_v<HostDataType, HOST_FLOAT>)
14721471 {
1472+ const HostDataType test_value_zero =
1473+ static_cast <HostDataType>(0 .0f );
1474+ const HostDataType test_value_minus_zero =
1475+ static_cast <HostDataType>(-0 .0f );
1476+ const HostDataType test_value_without_fraction =
1477+ static_cast <HostDataType>(2 .0f );
1478+ const HostDataType test_value_with_fraction =
1479+ static_cast <HostDataType>(2 .2f );
1480+
14731481 if (special_values.empty ())
14741482 {
14751483 special_values = {
@@ -1488,10 +1496,21 @@ class CBasicTestFetchAddSpecialFloats
14881496 std::numeric_limits<HostDataType>::max (),
14891497 };
14901498
1491- if (0 != (CL_FP_DENORM & gFloatFPConfig ))
1499+ if constexpr (std::is_same_v<HostDataType, HOST_DOUBLE>)
1500+ {
1501+ if (0 != (CL_FP_DENORM & gDoubleFPConfig ))
1502+ {
1503+ special_values.push_back (
1504+ std::numeric_limits<HostDataType>::denorm_min ());
1505+ }
1506+ }
1507+ else if constexpr (std::is_same_v<HostDataType, HOST_FLOAT>)
14921508 {
1493- special_values.push_back (
1494- std::numeric_limits<HostDataType>::denorm_min ());
1509+ if (0 != (CL_FP_DENORM & gFloatFPConfig ))
1510+ {
1511+ special_values.push_back (
1512+ std::numeric_limits<HostDataType>::denorm_min ());
1513+ }
14951514 }
14961515 }
14971516 }
@@ -1524,7 +1543,6 @@ class CBasicTestFetchAddSpecialFloats
15241543 }
15251544 }
15261545 }
1527-
15281546 return special_values;
15291547 }
15301548
@@ -1534,7 +1552,7 @@ class CBasicTestFetchAddSpecialFloats
15341552 if constexpr (
15351553 std::is_same_v<
15361554 HostDataType,
1537- HOST_HALF> || std::is_same_v<HostDataType, HOST_FLOAT>)
1555+ HOST_HALF> || std::is_same_v<HostDataType, HOST_DOUBLE> || std::is_same_v<HostDataType, HOST_FLOAT>)
15381556 {
15391557 if (threadCount > ref_vals.size ())
15401558 {
@@ -1568,7 +1586,7 @@ class CBasicTestFetchAddSpecialFloats
15681586 if constexpr (
15691587 std::is_same_v<
15701588 HostDataType,
1571- HOST_HALF> || std::is_same_v<HostDataType, HOST_FLOAT>)
1589+ HOST_HALF> || std::is_same_v<HostDataType, HOST_DOUBLE> || std::is_same_v<HostDataType, HOST_FLOAT>)
15721590 {
15731591 // The start_value variable (set by StartValue) is used
15741592 // as a divisor of the thread index when selecting the operand for
@@ -1597,7 +1615,7 @@ class CBasicTestFetchAddSpecialFloats
15971615 if constexpr (
15981616 std::is_same_v<
15991617 HostDataType,
1600- HOST_HALF> || std::is_same_v<HostDataType, HOST_FLOAT>)
1618+ HOST_HALF> || std::is_same_v<HostDataType, HOST_DOUBLE> || std::is_same_v<HostDataType, HOST_FLOAT>)
16011619 {
16021620 auto spec_vals = GetSpecialValues ();
16031621 host_atomic_store (&destMemory[tid], (HostDataType)oldValues[tid],
@@ -1612,8 +1630,10 @@ class CBasicTestFetchAddSpecialFloats
16121630 cl_uint whichDestValue) override
16131631 {
16141632 expected = StartValue ();
1615-
1616- if constexpr (std::is_same_v<HostDataType, HOST_FLOAT>)
1633+ if constexpr (
1634+ std::is_same_v<
1635+ HostDataType,
1636+ HOST_DOUBLE> || std::is_same_v<HostDataType, HOST_FLOAT>)
16171637 {
16181638 auto spec_vals = GetSpecialValues ();
16191639 expected = startRefValues[whichDestValue]
@@ -1635,17 +1655,17 @@ class CBasicTestFetchAddSpecialFloats
16351655 const std::vector<HostAtomicType> &testValues,
16361656 cl_uint whichDestValue) override
16371657 {
1638- if constexpr (std::is_same_v<HostDataType, HOST_FLOAT>)
1658+ if constexpr (std::is_same_v<HostDataType, HOST_HALF>)
1659+ {
1660+ return static_cast <cl_half>(expected) != testValues[whichDestValue];
1661+ }
1662+ else
16391663 {
16401664 if (std::isnan (testValues[whichDestValue]) && std::isnan (expected))
16411665 return false ;
16421666 else
16431667 return expected != testValues[whichDestValue];
16441668 }
1645- else if constexpr (std::is_same_v<HostDataType, HOST_HALF>)
1646- {
1647- return static_cast <cl_half>(expected) != testValues[whichDestValue];
1648- }
16491669
16501670 return CBasicTestMemOrderScope<
16511671 HostAtomicType, HostDataType>::IsTestNotAsExpected (expected,
@@ -1655,6 +1675,25 @@ class CBasicTestFetchAddSpecialFloats
16551675 int ExecuteSingleTest (cl_device_id deviceID, cl_context context,
16561676 cl_command_queue queue) override
16571677 {
1678+ if constexpr (std::is_same_v<HostDataType, HOST_DOUBLE>)
1679+ {
1680+ if (LocalMemory ()
1681+ && (gDoubleAtomicCaps & CL_DEVICE_LOCAL_FP_ATOMIC_ADD_EXT) == 0 )
1682+ return 0 ; // skip test - not applicable
1683+
1684+ if (!LocalMemory ()
1685+ && (gDoubleAtomicCaps & CL_DEVICE_GLOBAL_FP_ATOMIC_ADD_EXT)
1686+ == 0 )
1687+ return 0 ;
1688+
1689+ if (!CBasicTestMemOrderScope<HostAtomicType,
1690+ HostDataType>::LocalMemory ()
1691+ && CBasicTestMemOrderScope<HostAtomicType,
1692+ HostDataType>::DeclaredInProgram ())
1693+ {
1694+ if ((gDoubleFPConfig & CL_FP_INF_NAN) == 0 ) return 0 ;
1695+ }
1696+ }
16581697 if constexpr (std::is_same_v<HostDataType, HOST_FLOAT>)
16591698 {
16601699 if (LocalMemory ()
@@ -1702,7 +1741,7 @@ class CBasicTestFetchAddSpecialFloats
17021741 if constexpr (
17031742 std::is_same_v<
17041743 HostDataType,
1705- HOST_HALF> || std::is_same_v<HostDataType, HOST_FLOAT>)
1744+ HOST_HALF> || std::is_same_v<HostDataType, HOST_DOUBLE> || std::is_same_v<HostDataType, HOST_FLOAT>)
17061745 {
17071746 return threadCount;
17081747 }
@@ -1737,6 +1776,17 @@ static int test_atomic_fetch_add_generic(cl_device_id deviceID,
17371776
17381777 if (gFloatAtomicsSupported )
17391778 {
1779+ auto spec_vals_fp64 =
1780+ CBasicTestFetchAddSpecialFloats<HOST_ATOMIC_DOUBLE,
1781+ HOST_DOUBLE>::GetSpecialValues ();
1782+
1783+ CBasicTestFetchAddSpecialFloats<HOST_ATOMIC_DOUBLE, HOST_DOUBLE>
1784+ test_spec_double (TYPE_ATOMIC_DOUBLE, useSVM);
1785+ EXECUTE_TEST (error,
1786+ test_spec_double.Execute (deviceID, context, queue,
1787+ spec_vals_fp64.size ()
1788+ * spec_vals_fp64.size ()));
1789+
17401790 auto spec_vals_fp32 =
17411791 CBasicTestFetchAddSpecialFloats<HOST_ATOMIC_FLOAT,
17421792 HOST_FLOAT>::GetSpecialValues ();
0 commit comments