Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added cl_khr_fp16 extension support for test_commonfns #1695

Merged
merged 15 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
// limitations under the License.
//

#ifndef BASIC_UTILS_H
#define BASIC_UTILS_H
#ifndef STRING_HELPERS_H
#define STRING_HELPERS_H

#include <memory>
#include <string>
Expand All @@ -38,4 +38,4 @@ inline std::string str_sprintf(const std::string &str, Args... args)
return std::string(buffer.get(), buffer.get() + s - 1);
}

#endif // BASIC_UTIL_H
#endif // STRING_HELPERS_H
2 changes: 1 addition & 1 deletion test_conformance/basic/test_astype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
#include <vector>

#include "harness/conversions.h"
#include "harness/stringHelpers.h"
#include "harness/typeWrappers.h"

#include "procs.h"
#include "utils.h"

// clang-format off

Expand Down
43 changes: 33 additions & 10 deletions test_conformance/commonfns/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2023 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand All @@ -18,8 +18,10 @@
#include <string.h>
#include "procs.h"
#include "test_base.h"
#include "harness/kernelHelpers.h"

std::map<size_t, std::string> BaseFunctionTest::type2name;
cl_half_rounding_mode BaseFunctionTest::halfRoundingMode = CL_HALF_RTE;

int g_arrVecSizes[kVectorSizeCount + kStrangeVectorSizeCount];
int g_arrStrangeVectorSizes[kStrangeVectorSizeCount] = {3};
Expand All @@ -45,17 +47,38 @@ test_definition test_list[] = {

const int test_num = ARRAY_SIZE( test_list );

int main(int argc, const char *argv[])
test_status InitCL(cl_device_id device)
{
initVecSizes();

if (BaseFunctionTest::type2name.empty())
if (is_extension_available(device, "cl_khr_fp16"))
{
BaseFunctionTest::type2name[sizeof(half)] = "half";
BaseFunctionTest::type2name[sizeof(float)] = "float";
BaseFunctionTest::type2name[sizeof(double)] = "double";
const cl_device_fp_config fpConfigHalf =
get_default_rounding_mode(device, CL_DEVICE_HALF_FP_CONFIG);
if ((fpConfigHalf & CL_FP_ROUND_TO_NEAREST) != 0)
{
BaseFunctionTest::halfRoundingMode = CL_HALF_RTE;
}
else if ((fpConfigHalf & CL_FP_ROUND_TO_ZERO) != 0)
{
BaseFunctionTest::halfRoundingMode = CL_HALF_RTZ;
}
else
{
log_error("Error while acquiring half rounding mode");
return TEST_FAIL;
}
}

return runTestHarness(argc, argv, test_num, test_list, false, 0);
return TEST_PASS;
}

int main(int argc, const char *argv[])
{
initVecSizes();

BaseFunctionTest::type2name[sizeof(half)] = "half";
BaseFunctionTest::type2name[sizeof(float)] = "float";
BaseFunctionTest::type2name[sizeof(double)] = "double";

return runTestHarnessWithCheck(argc, argv, test_num, test_list, false, 0,
InitCL);
}
86 changes: 63 additions & 23 deletions test_conformance/commonfns/test_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,23 @@
#include <vector>
#include <map>
#include <memory>
#include <cmath>

#include <CL/cl_half.h>
#include <CL/cl_ext.h>

#include "harness/deviceInfo.h"
#include "harness/testHarness.h"
#include "harness/typeWrappers.h"


template <typename T>
using VerifyFuncBinary = int (*)(const T *const, const T *const, const T *const,
const int num, const int vs, const int vp);


template <typename T>
using VerifyFuncUnary = int (*)(const T *const, const T *const, const int num);


using half = cl_half;


struct BaseFunctionTest
{
BaseFunctionTest(cl_device_id device, cl_context context,
Expand All @@ -61,9 +57,9 @@ struct BaseFunctionTest
bool vecParam;

static std::map<size_t, std::string> type2name;
static cl_half_rounding_mode halfRoundingMode;
};


struct MinTest : BaseFunctionTest
{
MinTest(cl_device_id device, cl_context context, cl_command_queue queue,
Expand All @@ -74,7 +70,6 @@ struct MinTest : BaseFunctionTest
cl_int Run() override;
};


struct MaxTest : BaseFunctionTest
{
MaxTest(cl_device_id device, cl_context context, cl_command_queue queue,
Expand All @@ -85,7 +80,6 @@ struct MaxTest : BaseFunctionTest
cl_int Run() override;
};


struct ClampTest : BaseFunctionTest
{
ClampTest(cl_device_id device, cl_context context, cl_command_queue queue,
Expand All @@ -96,7 +90,6 @@ struct ClampTest : BaseFunctionTest
cl_int Run() override;
};


struct DegreesTest : BaseFunctionTest
{
DegreesTest(cl_device_id device, cl_context context, cl_command_queue queue,
Expand All @@ -107,7 +100,6 @@ struct DegreesTest : BaseFunctionTest
cl_int Run() override;
};


struct RadiansTest : BaseFunctionTest
{
RadiansTest(cl_device_id device, cl_context context, cl_command_queue queue,
Expand All @@ -118,7 +110,6 @@ struct RadiansTest : BaseFunctionTest
cl_int Run() override;
};


struct SignTest : BaseFunctionTest
{
SignTest(cl_device_id device, cl_context context, cl_command_queue queue,
Expand All @@ -129,7 +120,6 @@ struct SignTest : BaseFunctionTest
cl_int Run() override;
};


struct SmoothstepTest : BaseFunctionTest
{
SmoothstepTest(cl_device_id device, cl_context context,
Expand All @@ -141,7 +131,6 @@ struct SmoothstepTest : BaseFunctionTest
cl_int Run() override;
};


struct StepTest : BaseFunctionTest
{
StepTest(cl_device_id device, cl_context context, cl_command_queue queue,
Expand All @@ -152,7 +141,6 @@ struct StepTest : BaseFunctionTest
cl_int Run() override;
};


struct MixTest : BaseFunctionTest
{
MixTest(cl_device_id device, cl_context context, cl_command_queue queue,
Expand All @@ -163,19 +151,71 @@ struct MixTest : BaseFunctionTest
cl_int Run() override;
};

template <typename T> float UlpFn(const T &val, const double &r)
{
if (std::is_same<T, half>::value)
{
return Ulp_Error_Half(val, r);
}
else if (std::is_same<T, float>::value)
{
return Ulp_Error(val, r);
}
else if (std::is_same<T, double>::value)
{
return Ulp_Error_Double(val, r);
}
else
{
log_error("UlpFn: unsupported data type\n");
}

return -1.f; // wrong val
}

template <typename T> inline double conv_to_dbl(const T &val)
{
if (std::is_same<T, half>::value)
return (double)cl_half_to_float(val);
else
return (double)val;
}

template <typename... Args>
std::string string_format(const std::string &format, Args... args)
template <typename T> inline double conv_to_flt(const T &val)
{
int sformat = std::snprintf(nullptr, 0, format.c_str(), args...) + 1;
if (sformat <= 0)
throw std::runtime_error("string_format: string processing error.");
auto format_size = static_cast<size_t>(sformat);
std::unique_ptr<char[]> buffer(new char[format_size]);
std::snprintf(buffer.get(), format_size, format.c_str(), args...);
return std::string(buffer.get(), buffer.get() + format_size - 1);
if (std::is_same<T, half>::value)
return (float)cl_half_to_float(val);
else
return (float)val;
}

template <typename T> inline half conv_to_half(const T &val)
{
if (std::is_floating_point<T>::value)
return cl_half_from_float(val, BaseFunctionTest::halfRoundingMode);
return 0;
}

template <typename T> bool isfinite_fp(const T &v)
{
if (std::is_same<T, half>::value)
{
// Extract FP16 exponent and mantissa
uint16_t h_exp = (((half)v) >> (CL_HALF_MANT_DIG - 1)) & 0x1F;
uint16_t h_mant = ((half)v) & 0x3FF;

// !Inf test
return !(h_exp == 0x1F && h_mant == 0);
}
else
{
#if !defined(_WIN32)
return std::isfinite(v);
#else
return isfinite(v);
#endif
}
}

template <class T>
int MakeAndRunTest(cl_device_id device, cl_context context,
Expand Down
Loading