mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-21 06:49:02 +00:00
Fp16 math bruteforce staging (#1863)
* Enable fp16 in math bruteforce * Added modernization of remaining half tests for consistency (issue #142, bruteforce) * Added kernel types related corrections * Added more fixes and general cleanup * Corrected ULP values for half tests (issue #142, bruteforce) * Corrected presubmit check for clang format * Added support for ternary, unary_two_result and unary_two_result_i tests for cl_half (issue #142, bruteforce) * Added missing condition due to vendor's review * code format correction * Added check for lack of support for denormals in binary_half scenario * Corrected procedure to compute nextafter cl_half for flush-to-zero mode * Added correction for external check of reference value for nextafter test * Added correction due to code review request * Changed quantity of tests performed for half in unary and macro_unary procedures from basic * Added corrections related to code review: -added binary_operator_half.cpp and binary_two_results_i_half.cpp -address sanitizer errors fixed -extending list of special half values -removed unnecessary relaxed math references in half tests -corrected conditions to verify ulp narrowing of computation results -several refactoring and cosmetics corrections * Print format correction due to failed CI check * Corrected bug found in code review (fp16 bruteforce) * Corrections related to code review (cl_khr_fp16 support according to #142) -gHostFill missing support added -special half values array extended -cosmetics and unifying * clang format applied * consistency correction * more consistency corrections for cl_fp16_khr supported tests * Corrections related to code review (bureforce #142) * Correction for i_unary_half test capacity * Corrections related to capacity of cl_khr_fp16 tests in bruteforce (#142) --------- Co-authored-by: Wawiorko, Grzegorz <grzegorz.wawiorko@intel.com>
This commit is contained in:
201
test_conformance/math_brute_force/mad_half.cpp
Normal file
201
test_conformance/math_brute_force/mad_half.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include "common.h"
|
||||
#include "function_list.h"
|
||||
#include "test_functions.h"
|
||||
#include "utility.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace {
|
||||
|
||||
cl_int BuildKernel_HalfFn(cl_uint job_id, cl_uint thread_id UNUSED, void *p)
|
||||
{
|
||||
BuildKernelInfo &info = *(BuildKernelInfo *)p;
|
||||
auto generator = [](const std::string &kernel_name, const char *builtin,
|
||||
cl_uint vector_size_index) {
|
||||
return GetTernaryKernel(kernel_name, builtin, ParameterType::Half,
|
||||
ParameterType::Half, ParameterType::Half,
|
||||
ParameterType::Half, vector_size_index);
|
||||
};
|
||||
return BuildKernels(info, job_id, generator);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int TestFunc_mad_Half(const Func *f, MTdata d, bool relaxedMode)
|
||||
{
|
||||
int error;
|
||||
Programs programs;
|
||||
KernelMatrix kernels;
|
||||
const unsigned thread_id = 0; // Test is currently not multithreaded.
|
||||
float maxError = 0.0f;
|
||||
|
||||
float maxErrorVal = 0.0f;
|
||||
float maxErrorVal2 = 0.0f;
|
||||
float maxErrorVal3 = 0.0f;
|
||||
size_t bufferSize = BUFFER_SIZE;
|
||||
|
||||
logFunctionInfo(f->name, sizeof(cl_half), relaxedMode);
|
||||
uint64_t step = getTestStep(sizeof(cl_half), bufferSize);
|
||||
|
||||
// Init the kernels
|
||||
{
|
||||
BuildKernelInfo build_info = { 1, kernels, programs, f->nameInCode };
|
||||
if ((error = ThreadPool_Do(BuildKernel_HalfFn,
|
||||
gMaxVectorSizeIndex - gMinVectorSizeIndex,
|
||||
&build_info)))
|
||||
return error;
|
||||
}
|
||||
for (uint64_t i = 0; i < (1ULL << 32); i += step)
|
||||
{
|
||||
// Init input array
|
||||
cl_ushort *p = (cl_ushort *)gIn;
|
||||
cl_ushort *p2 = (cl_ushort *)gIn2;
|
||||
cl_ushort *p3 = (cl_ushort *)gIn3;
|
||||
for (size_t j = 0; j < bufferSize / sizeof(cl_ushort); j++)
|
||||
{
|
||||
p[j] = (cl_ushort)genrand_int32(d);
|
||||
p2[j] = (cl_ushort)genrand_int32(d);
|
||||
p3[j] = (cl_ushort)genrand_int32(d);
|
||||
}
|
||||
if ((error = clEnqueueWriteBuffer(gQueue, gInBuffer, CL_FALSE, 0,
|
||||
bufferSize, gIn, 0, NULL, NULL)))
|
||||
{
|
||||
vlog_error("\n*** Error %d in clEnqueueWriteBuffer ***\n", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = clEnqueueWriteBuffer(gQueue, gInBuffer2, CL_FALSE, 0,
|
||||
bufferSize, gIn2, 0, NULL, NULL)))
|
||||
{
|
||||
vlog_error("\n*** Error %d in clEnqueueWriteBuffer2 ***\n", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = clEnqueueWriteBuffer(gQueue, gInBuffer3, CL_FALSE, 0,
|
||||
bufferSize, gIn3, 0, NULL, NULL)))
|
||||
{
|
||||
vlog_error("\n*** Error %d in clEnqueueWriteBuffer3 ***\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
// write garbage into output arrays
|
||||
for (auto j = gMinVectorSizeIndex; j < gMaxVectorSizeIndex; j++)
|
||||
{
|
||||
uint32_t pattern = 0xacdcacdc;
|
||||
if (gHostFill)
|
||||
{
|
||||
memset_pattern4(gOut[j], &pattern, BUFFER_SIZE);
|
||||
if ((error = clEnqueueWriteBuffer(gQueue, gOutBuffer[j],
|
||||
CL_FALSE, 0, BUFFER_SIZE,
|
||||
gOut[j], 0, NULL, NULL)))
|
||||
{
|
||||
vlog_error(
|
||||
"\n*** Error %d in clEnqueueWriteBuffer2(%d) ***\n",
|
||||
error, j);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = clEnqueueFillBuffer(gQueue, gOutBuffer[j], &pattern,
|
||||
sizeof(pattern), 0, BUFFER_SIZE, 0,
|
||||
NULL, NULL);
|
||||
test_error(error, "clEnqueueFillBuffer failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Run the kernels
|
||||
for (auto j = gMinVectorSizeIndex; j < gMaxVectorSizeIndex; j++)
|
||||
{
|
||||
size_t vectorSize = sizeof(cl_half) * sizeValues[j];
|
||||
size_t localCount = (bufferSize + vectorSize - 1)
|
||||
/ vectorSize; // bufferSize / vectorSize rounded up
|
||||
if ((error = clSetKernelArg(kernels[j][thread_id], 0,
|
||||
sizeof(gOutBuffer[j]), &gOutBuffer[j])))
|
||||
{
|
||||
LogBuildError(programs[j]);
|
||||
return error;
|
||||
}
|
||||
if ((error = clSetKernelArg(kernels[j][thread_id], 1,
|
||||
sizeof(gInBuffer), &gInBuffer)))
|
||||
{
|
||||
LogBuildError(programs[j]);
|
||||
return error;
|
||||
}
|
||||
if ((error = clSetKernelArg(kernels[j][thread_id], 2,
|
||||
sizeof(gInBuffer2), &gInBuffer2)))
|
||||
{
|
||||
LogBuildError(programs[j]);
|
||||
return error;
|
||||
}
|
||||
if ((error = clSetKernelArg(kernels[j][thread_id], 3,
|
||||
sizeof(gInBuffer3), &gInBuffer3)))
|
||||
{
|
||||
LogBuildError(programs[j]);
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((error = clEnqueueNDRangeKernel(gQueue, kernels[j][thread_id],
|
||||
1, NULL, &localCount, NULL, 0,
|
||||
NULL, NULL)))
|
||||
{
|
||||
vlog_error("FAILED -- could not execute kernel\n");
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Get that moving
|
||||
if ((error = clFlush(gQueue))) vlog("clFlush failed\n");
|
||||
|
||||
// Read the data back
|
||||
for (auto j = gMinVectorSizeIndex; j < gMaxVectorSizeIndex; j++)
|
||||
{
|
||||
if ((error =
|
||||
clEnqueueReadBuffer(gQueue, gOutBuffer[j], CL_TRUE, 0,
|
||||
bufferSize, gOut[j], 0, NULL, NULL)))
|
||||
{
|
||||
vlog_error("ReadArray failed %d\n", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (gSkipCorrectnessTesting) break;
|
||||
|
||||
// Verify data - no verification possible. MAD is a random number
|
||||
// generator.
|
||||
|
||||
if (0 == (i & 0x0fffffff))
|
||||
{
|
||||
vlog(".");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gSkipCorrectnessTesting)
|
||||
{
|
||||
if (gWimpyMode)
|
||||
vlog("Wimp pass");
|
||||
else
|
||||
vlog("pass");
|
||||
|
||||
vlog("\t%8.2f @ {%a, %a, %a}", maxError, maxErrorVal, maxErrorVal2,
|
||||
maxErrorVal3);
|
||||
}
|
||||
vlog("\n");
|
||||
|
||||
return error;
|
||||
}
|
||||
Reference in New Issue
Block a user