mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-23 23:49:02 +00:00
Initial open source release of OpenCL 2.2 CTS.
This commit is contained in:
12
test_conformance/clcpp/address_spaces/CMakeLists.txt
Normal file
12
test_conformance/clcpp/address_spaces/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
set(MODULE_NAME CPP_ADDRESS_SPACES)
|
||||
|
||||
set(${MODULE_NAME}_SOURCES
|
||||
main.cpp
|
||||
../../../test_common/harness/errorHelpers.c
|
||||
../../../test_common/harness/testHarness.c
|
||||
../../../test_common/harness/kernelHelpers.c
|
||||
../../../test_common/harness/msvc9.c
|
||||
../../../test_common/harness/parseParameters.cpp
|
||||
)
|
||||
|
||||
include(../../CMakeCommon.txt)
|
||||
203
test_conformance/clcpp/address_spaces/common.hpp
Normal file
203
test_conformance/clcpp/address_spaces/common.hpp
Normal file
@@ -0,0 +1,203 @@
|
||||
//
|
||||
// Copyright (c) 2017 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.
|
||||
//
|
||||
#ifndef TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_COMMON_HPP
|
||||
#define TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_COMMON_HPP
|
||||
|
||||
#include "../common.hpp"
|
||||
#include "../funcs_test_utils.hpp"
|
||||
|
||||
#define RUN_ADDRESS_SPACES_TEST_MACRO(TEST_CLASS) \
|
||||
last_error = run_address_spaces_test( \
|
||||
device, context, queue, n_elems, TEST_CLASS \
|
||||
); \
|
||||
CHECK_ERROR(last_error) \
|
||||
error |= last_error;
|
||||
|
||||
// This is a base class for address spaces tests.
|
||||
template <class T>
|
||||
struct address_spaces_test : public detail::base_func_type<T>
|
||||
{
|
||||
// output buffer type
|
||||
typedef T type;
|
||||
|
||||
virtual ~address_spaces_test() {};
|
||||
// Returns test name
|
||||
virtual std::string str() = 0;
|
||||
// Returns OpenCL program source
|
||||
virtual std::string generate_program() = 0;
|
||||
// Returns kernel names IN ORDER
|
||||
virtual std::vector<std::string> get_kernel_names()
|
||||
{
|
||||
// Typical case, that is, only one kernel
|
||||
return { this->get_kernel_name() };
|
||||
}
|
||||
|
||||
// Return value that is expected to be in output_buffer[i]
|
||||
virtual T operator()(size_t i, size_t work_group_size) = 0;
|
||||
|
||||
// If local size has to be set in clEnqueueNDRangeKernel()
|
||||
// this should return true; otherwise - false;
|
||||
virtual bool set_local_size()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculates maximal work-group size (one dim)
|
||||
virtual size_t get_max_local_size(const std::vector<cl_kernel>& kernels,
|
||||
cl_device_id device,
|
||||
size_t work_group_size, // default work-group size
|
||||
cl_int& error)
|
||||
{
|
||||
size_t wg_size = work_group_size;
|
||||
for(auto&k : kernels)
|
||||
{
|
||||
size_t max_wg_size;
|
||||
error = clGetKernelWorkGroupInfo(k, device, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &max_wg_size, NULL);
|
||||
RETURN_ON_CL_ERROR(error, "clGetKernelWorkGroupInfo")
|
||||
wg_size = (std::min)(max_wg_size, wg_size);
|
||||
}
|
||||
return wg_size;
|
||||
}
|
||||
|
||||
// This covers typical case: each kernel is executed once, every kernel
|
||||
// has only one argument which is output buffer
|
||||
virtual cl_int execute(const std::vector<cl_kernel>& kernels,
|
||||
cl_mem& output_buffer,
|
||||
cl_command_queue& queue,
|
||||
size_t work_size,
|
||||
size_t work_group_size)
|
||||
{
|
||||
cl_int err;
|
||||
for(auto& k : kernels)
|
||||
{
|
||||
err = clSetKernelArg(k, 0, sizeof(output_buffer), &output_buffer);
|
||||
RETURN_ON_CL_ERROR(err, "clSetKernelArg");
|
||||
|
||||
err = clEnqueueNDRangeKernel(
|
||||
queue, k, 1,
|
||||
NULL, &work_size, this->set_local_size() ? &work_group_size : NULL,
|
||||
0, NULL, NULL
|
||||
);
|
||||
RETURN_ON_CL_ERROR(err, "clEnqueueNDRangeKernel");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
template <class address_spaces_test>
|
||||
int run_address_spaces_test(cl_device_id device, cl_context context, cl_command_queue queue, size_t count, address_spaces_test op)
|
||||
{
|
||||
cl_mem buffers[1];
|
||||
cl_program program;
|
||||
std::vector<cl_kernel> kernels;
|
||||
size_t wg_size;
|
||||
size_t work_size[1];
|
||||
cl_int err;
|
||||
|
||||
typedef typename address_spaces_test::type TYPE;
|
||||
|
||||
// Don't run test for unsupported types
|
||||
if(!(type_supported<TYPE>(device)))
|
||||
{
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
std::string code_str = op.generate_program();
|
||||
std::vector<std::string> kernel_names = op.get_kernel_names();
|
||||
if(kernel_names.empty())
|
||||
{
|
||||
RETURN_ON_ERROR_MSG(-1, "No kernel to run");
|
||||
}
|
||||
kernels.resize(kernel_names.size());
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Only OpenCL C++ to SPIR-V compilation
|
||||
#if defined(DEVELOPMENT) && defined(ONLY_SPIRV_COMPILATION)
|
||||
err = create_opencl_kernel(context, &program, &(kernels[0]), code_str, kernel_names[0]);
|
||||
return err;
|
||||
// Use OpenCL C kernels instead of OpenCL C++ kernels (test C++ host code)
|
||||
#elif defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
err = create_opencl_kernel(context, &program, &(kernels[0]), code_str, kernel_names[0], "-cl-std=CL2.0", false);
|
||||
RETURN_ON_ERROR(err)
|
||||
for(size_t i = 1; i < kernels.size(); i++)
|
||||
{
|
||||
kernels[i] = clCreateKernel(program, kernel_names[i].c_str(), &err);
|
||||
RETURN_ON_CL_ERROR(err, "clCreateKernel");
|
||||
}
|
||||
#else
|
||||
err = create_opencl_kernel(context, &program, &(kernels[0]), code_str, kernel_names[0]);
|
||||
RETURN_ON_ERROR(err)
|
||||
for(size_t i = 1; i < kernels.size(); i++)
|
||||
{
|
||||
kernels[i] = clCreateKernel(program, kernel_names[i].c_str(), &err);
|
||||
RETURN_ON_CL_ERROR(err, "clCreateKernel");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the max possible wg size for among all the kernels
|
||||
wg_size = op.get_max_local_size(kernels, device, 1024, err);
|
||||
RETURN_ON_ERROR(err);
|
||||
|
||||
work_size[0] = count;
|
||||
if(op.set_local_size())
|
||||
{
|
||||
size_t wg_number = static_cast<size_t>(
|
||||
std::ceil(static_cast<double>(count) / wg_size)
|
||||
);
|
||||
work_size[0] = wg_number * wg_size;
|
||||
}
|
||||
|
||||
// output on host
|
||||
std::vector<TYPE> output = generate_output<TYPE>(work_size[0], 9999);
|
||||
|
||||
// output buffer
|
||||
buffers[0] = clCreateBuffer
|
||||
(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(TYPE) * output.size(), NULL, &err
|
||||
);
|
||||
RETURN_ON_CL_ERROR(err, "clCreateBuffer")
|
||||
|
||||
// Execute test
|
||||
err = op.execute(kernels, buffers[0], queue, work_size[0], wg_size);
|
||||
RETURN_ON_ERROR(err)
|
||||
|
||||
err = clEnqueueReadBuffer(
|
||||
queue, buffers[0], CL_TRUE, 0, sizeof(TYPE) * output.size(),
|
||||
static_cast<void *>(output.data()), 0, NULL, NULL
|
||||
);
|
||||
RETURN_ON_CL_ERROR(err, "clEnqueueReadBuffer");
|
||||
|
||||
for(size_t i = 0; i < output.size(); i++)
|
||||
{
|
||||
TYPE v = op(i, wg_size);
|
||||
if(!(are_equal(v, output[i], detail::make_value<TYPE>(0), op)))
|
||||
{
|
||||
RETURN_ON_ERROR_MSG(-1,
|
||||
"test_%s(%s) failed. Expected: %s, got: %s", op.str().c_str(), type_name<TYPE>().c_str(),
|
||||
format_value(v).c_str(), format_value(output[i]).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
log_info("test_%s(%s) passed\n", op.str().c_str(), type_name<TYPE>().c_str());
|
||||
|
||||
clReleaseMemObject(buffers[0]);
|
||||
for(auto& k : kernels)
|
||||
clReleaseKernel(k);
|
||||
clReleaseProgram(program);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif // TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_COMMON_HPP
|
||||
30
test_conformance/clcpp/address_spaces/main.cpp
Normal file
30
test_conformance/clcpp/address_spaces/main.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright (c) 2017 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.hpp"
|
||||
|
||||
#include "test_pointer_types.hpp"
|
||||
#include "test_storage_types.hpp"
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
// Get list to all test functions
|
||||
std::vector<basefn> testfn_list = autotest::test_suite::get_test_functions();
|
||||
// Get names of all test functions
|
||||
std::vector<std::string> testfn_names = autotest::test_suite::get_test_names();
|
||||
// Create a vector of pointers to the names test functions
|
||||
std::vector<const char *> testfn_names_c_str = autotest::get_strings_ptrs(testfn_names);
|
||||
return runTestHarness(argc, argv, testfn_list.size(), testfn_list.data(), testfn_names_c_str.data(), false, false, 0);
|
||||
}
|
||||
411
test_conformance/clcpp/address_spaces/test_pointer_types.hpp
Normal file
411
test_conformance/clcpp/address_spaces/test_pointer_types.hpp
Normal file
@@ -0,0 +1,411 @@
|
||||
//
|
||||
// Copyright (c) 2017 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.
|
||||
//
|
||||
#ifndef TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_TEST_POINTER_TYPES_HPP
|
||||
#define TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_TEST_POINTER_TYPES_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
// ----------------------------
|
||||
// ---------- PRIVATE
|
||||
// ----------------------------
|
||||
|
||||
template <class T>
|
||||
struct private_pointer_test : public address_spaces_test<T>
|
||||
{
|
||||
std::string str()
|
||||
{
|
||||
return "private_pointer";
|
||||
}
|
||||
|
||||
T operator()(size_t i, size_t work_group_size)
|
||||
{
|
||||
typedef typename scalar_type<T>::type SCALAR;
|
||||
(void) work_group_size;
|
||||
return detail::make_value<T>(static_cast<SCALAR>(i));
|
||||
}
|
||||
|
||||
// Each work-item writes its global id to output[work-item-global-id]
|
||||
std::string generate_program()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
#if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
return
|
||||
"__kernel void " + this->get_kernel_name() + "(global " + type_name<T>() + " *output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = (" + type_name<T>() + ")(gid);\n"
|
||||
"}\n";
|
||||
|
||||
#else
|
||||
return
|
||||
"#include <opencl_memory>\n"
|
||||
"#include <opencl_work_item>\n"
|
||||
"#include <opencl_array>\n"
|
||||
"using namespace cl;\n"
|
||||
"__kernel void " + this->get_kernel_name() + "(global_ptr<" + type_name<T>() + "[]> output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" typedef " + type_name<T>() + " TYPE;\n"
|
||||
" TYPE v = TYPE(gid);\n"
|
||||
" private_ptr<TYPE> v_ptr1(dynamic_asptr_cast<private_ptr<TYPE>>(&v));\n"
|
||||
" private_ptr<TYPE> v_ptr2(v_ptr1);\n"
|
||||
" TYPE a[] = { TYPE(0), TYPE(1) };\n"
|
||||
" private_ptr<TYPE> a_ptr = dynamic_asptr_cast<private_ptr<TYPE>>(a);\n"
|
||||
" a_ptr++;\n"
|
||||
" TYPE * a_ptr2 = a_ptr.get();\n"
|
||||
" *a_ptr2 = *v_ptr2;\n"
|
||||
" output[gid] = a[1];\n"
|
||||
"}\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
AUTO_TEST_CASE(test_private_pointer)
|
||||
(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
int last_error = CL_SUCCESS;
|
||||
|
||||
// private pointer
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_pointer_test<cl_uint>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_pointer_test<cl_float2>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_pointer_test<cl_float4>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_pointer_test<cl_float8>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_pointer_test<cl_uint16>());
|
||||
|
||||
if(error != CL_SUCCESS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// ---------- LOCAL
|
||||
// ----------------------------
|
||||
|
||||
template <class T>
|
||||
struct local_pointer_test : public address_spaces_test<T>
|
||||
{
|
||||
std::string str()
|
||||
{
|
||||
return "local_pointer";
|
||||
}
|
||||
|
||||
T operator()(size_t i, size_t work_group_size)
|
||||
{
|
||||
typedef typename scalar_type<T>::type SCALAR;
|
||||
size_t r = i / work_group_size;
|
||||
return detail::make_value<T>(static_cast<SCALAR>(r));
|
||||
}
|
||||
|
||||
bool set_local_size()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t get_max_local_size(const std::vector<cl_kernel>& kernels,
|
||||
cl_device_id device,
|
||||
size_t work_group_size, // default work-group size
|
||||
cl_int& error)
|
||||
{
|
||||
// Set size of the local memory, we need to to this to correctly calculate
|
||||
// max possible work-group size.
|
||||
// Additionally this already set 2nd argument of the test kernel, so we don't
|
||||
// have to modify execute() method.
|
||||
error = clSetKernelArg(kernels[0], 1, sizeof(cl_uint), NULL);
|
||||
RETURN_ON_CL_ERROR(error, "clSetKernelArg");
|
||||
|
||||
size_t wg_size;
|
||||
error = clGetKernelWorkGroupInfo(
|
||||
kernels[0], device, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &wg_size, NULL
|
||||
);
|
||||
RETURN_ON_CL_ERROR(error, "clGetKernelWorkGroupInfo")
|
||||
wg_size = wg_size <= work_group_size ? wg_size : work_group_size;
|
||||
return wg_size;
|
||||
}
|
||||
|
||||
// Every work-item writes id of its work-group to output[work-item-global-id]
|
||||
std::string generate_program()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
#if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
return
|
||||
"__kernel void " + this->get_kernel_name() + "(global " + type_name<T>() + " *output, "
|
||||
"local uint * local_mem_ptr)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = (" + type_name<T>() + ")(get_group_id(0));\n"
|
||||
"}\n";
|
||||
|
||||
#else
|
||||
return
|
||||
"#include <opencl_memory>\n"
|
||||
"#include <opencl_work_item>\n"
|
||||
"#include <opencl_synchronization>\n"
|
||||
"#include <opencl_array>\n"
|
||||
"using namespace cl;\n"
|
||||
"__kernel void " + this->get_kernel_name() + "(global_ptr<" + type_name<T>() + "[]> output, "
|
||||
"local_ptr<uint[]> local_mem_ptr)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" size_t lid = get_local_id(0);\n"
|
||||
" typedef " + type_name<T>() + " TYPE;\n"
|
||||
// 1st work-item in work-group writes get_group_id() to var
|
||||
" local<uint> var;\n"
|
||||
" local_ptr<uint> var_ptr = var.ptr();\n"
|
||||
" if(lid == 0) { *var_ptr = get_group_id(0); }\n"
|
||||
" work_group_barrier(mem_fence::local);\n"
|
||||
// last work-item in work-group writes var to 1st element of local_mem
|
||||
" local_ptr<uint[]> local_mem_ptr2(local_mem_ptr);\n"
|
||||
" auto local_mem_ptr3 = local_mem_ptr2.release();\n"
|
||||
" if(lid == (get_local_size(0) - 1)) { *(local_mem_ptr3) = var; }\n"
|
||||
" work_group_barrier(mem_fence::local);\n"
|
||||
// each work-item in work-group writes local_mem_ptr[0] to output[work-item-global-id]
|
||||
" output[gid] = local_mem_ptr[0];\n"
|
||||
"}\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
AUTO_TEST_CASE(test_local_pointer)
|
||||
(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
int last_error = CL_SUCCESS;
|
||||
|
||||
// local pointer
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_pointer_test<cl_uint>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_pointer_test<cl_float2>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_pointer_test<cl_float4>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_pointer_test<cl_float8>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_pointer_test<cl_uint16>());
|
||||
|
||||
if(error != CL_SUCCESS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// ---------- GLOBAL
|
||||
// ----------------------------
|
||||
|
||||
template <class T>
|
||||
struct global_pointer_test : public address_spaces_test<T>
|
||||
{
|
||||
std::string str()
|
||||
{
|
||||
return "global_pointer";
|
||||
}
|
||||
|
||||
T operator()(size_t i, size_t work_group_size)
|
||||
{
|
||||
typedef typename scalar_type<T>::type SCALAR;
|
||||
(void) work_group_size;
|
||||
return detail::make_value<T>(static_cast<SCALAR>(i));
|
||||
}
|
||||
|
||||
// Each work-item writes its global id to output[work-item-global-id]
|
||||
std::string generate_program()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
#if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
return
|
||||
"__kernel void " + this->get_kernel_name() + "(global " + type_name<T>() + " *output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = (" + type_name<T>() + ")(gid);\n"
|
||||
"}\n";
|
||||
|
||||
#else
|
||||
return
|
||||
"#include <opencl_memory>\n"
|
||||
"#include <opencl_work_item>\n"
|
||||
"#include <opencl_array>\n"
|
||||
"using namespace cl;\n"
|
||||
"typedef " + type_name<T>() + " TYPE;\n"
|
||||
"void set_to_gid(global_ptr<TYPE> ptr)\n"
|
||||
"{\n"
|
||||
" *ptr = TYPE(get_global_id(0));"
|
||||
"}\n"
|
||||
"__kernel void " + this->get_kernel_name() + "(global_ptr<TYPE[]> output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" auto ptr = output.get();\n"
|
||||
" global_ptr<TYPE> ptr2(ptr);\n"
|
||||
" ptr2 += ptrdiff_t(gid);\n"
|
||||
" set_to_gid(ptr2);\n"
|
||||
"}\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
AUTO_TEST_CASE(test_global_pointer)
|
||||
(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
int last_error = CL_SUCCESS;
|
||||
|
||||
// global pointer
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_pointer_test<cl_uint>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_pointer_test<cl_float2>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_pointer_test<cl_float4>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_pointer_test<cl_float8>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_pointer_test<cl_uint16>());
|
||||
|
||||
if(error != CL_SUCCESS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// ---------- CONSTANT
|
||||
// ----------------------------
|
||||
|
||||
template <class T>
|
||||
struct constant_pointer_test : public address_spaces_test<T>
|
||||
{
|
||||
// m_test_value is just a random value we use in this test.
|
||||
constant_pointer_test() : m_test_value(0xdeaddeadU)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string str()
|
||||
{
|
||||
return "constant_pointer";
|
||||
}
|
||||
|
||||
T operator()(size_t i, size_t work_group_size)
|
||||
{
|
||||
typedef typename scalar_type<T>::type SCALAR;
|
||||
(void) work_group_size;
|
||||
return detail::make_value<T>(static_cast<SCALAR>(m_test_value));
|
||||
}
|
||||
|
||||
// Each work-item writes m_test_value to output[work-item-global-id]
|
||||
std::string generate_program()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
#if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
return
|
||||
"__kernel void " + this->get_kernel_name() + "(global " + type_name<T>() + " *output, "
|
||||
"constant uint * const_ptr)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = (" + type_name<T>() + ")(const_ptr[0]);\n"
|
||||
"}\n";
|
||||
|
||||
#else
|
||||
return
|
||||
"#include <opencl_memory>\n"
|
||||
"#include <opencl_work_item>\n"
|
||||
"#include <opencl_array>\n"
|
||||
"using namespace cl;\n"
|
||||
"typedef " + type_name<T>() + " TYPE;\n"
|
||||
"__kernel void " + this->get_kernel_name() + "(global_ptr<TYPE[]> output, "
|
||||
"constant_ptr<uint[]> const_ptr)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" constant_ptr<uint[]> const_ptr2 = const_ptr;\n"
|
||||
" auto const_ptr3 = const_ptr2.get();\n"
|
||||
" output[gid] = *const_ptr3;\n"
|
||||
"}\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
// execute() method needs to be modified, to create additional buffer
|
||||
// and set it in 2nd arg (constant_ptr<uint[]> const_ptr)
|
||||
cl_int execute(const std::vector<cl_kernel>& kernels,
|
||||
cl_mem& output_buffer,
|
||||
cl_command_queue& queue,
|
||||
size_t work_size,
|
||||
size_t work_group_size)
|
||||
{
|
||||
cl_int err;
|
||||
|
||||
// Get context from queue
|
||||
cl_context context;
|
||||
err = clGetCommandQueueInfo(queue, CL_QUEUE_CONTEXT, sizeof(cl_context), &context, NULL);
|
||||
RETURN_ON_CL_ERROR(err, "clGetCommandQueueInfo");
|
||||
|
||||
// Create constant buffer
|
||||
auto const_buff = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_ONLY), sizeof(cl_uint), NULL, &err);
|
||||
RETURN_ON_CL_ERROR(err, "clCreateBuffer");
|
||||
|
||||
// Write m_test_value to const_buff
|
||||
err = clEnqueueWriteBuffer(
|
||||
queue, const_buff, CL_TRUE, 0, sizeof(cl_uint),
|
||||
static_cast<void *>(&m_test_value), 0, NULL, NULL
|
||||
);
|
||||
RETURN_ON_CL_ERROR(err, "clEnqueueWriteBuffer");
|
||||
|
||||
err = clSetKernelArg(kernels[0], 0, sizeof(output_buffer), &output_buffer);
|
||||
err |= clSetKernelArg(kernels[0], 1, sizeof(const_buff), &const_buff);
|
||||
RETURN_ON_CL_ERROR(err, "clSetKernelArg");
|
||||
|
||||
err = clEnqueueNDRangeKernel(
|
||||
queue, kernels[0], 1, NULL, &work_size, this->set_local_size() ? &work_group_size : NULL, 0, NULL, NULL
|
||||
);
|
||||
RETURN_ON_CL_ERROR(err, "clEnqueueNDRangeKernel");
|
||||
|
||||
err = clFinish(queue);
|
||||
RETURN_ON_CL_ERROR(err, "clFinish");
|
||||
|
||||
err = clReleaseMemObject(const_buff);
|
||||
RETURN_ON_CL_ERROR(err, "clReleaseMemObject");
|
||||
return err;
|
||||
}
|
||||
|
||||
private:
|
||||
cl_uint m_test_value;
|
||||
};
|
||||
|
||||
AUTO_TEST_CASE(test_constant_pointer)
|
||||
(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
int last_error = CL_SUCCESS;
|
||||
|
||||
// constant pointer
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_pointer_test<cl_uint>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_pointer_test<cl_float2>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_pointer_test<cl_float4>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_pointer_test<cl_float8>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_pointer_test<cl_uint16>());
|
||||
|
||||
if(error != CL_SUCCESS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_TEST_POINTER_TYPES_HPP
|
||||
418
test_conformance/clcpp/address_spaces/test_storage_types.hpp
Normal file
418
test_conformance/clcpp/address_spaces/test_storage_types.hpp
Normal file
@@ -0,0 +1,418 @@
|
||||
//
|
||||
// Copyright (c) 2017 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.
|
||||
//
|
||||
#ifndef TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_TEST_STORAGE_TYPES_HPP
|
||||
#define TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_TEST_STORAGE_TYPES_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
// ----------------------------
|
||||
// ---------- PRIVATE
|
||||
// ----------------------------
|
||||
|
||||
template <class T>
|
||||
struct private_storage_test : public address_spaces_test<T>
|
||||
{
|
||||
std::string str()
|
||||
{
|
||||
return "private_storage";
|
||||
}
|
||||
|
||||
T operator()(size_t i, size_t work_group_size)
|
||||
{
|
||||
typedef typename scalar_type<T>::type SCALAR;
|
||||
(void) work_group_size;
|
||||
return detail::make_value<T>(static_cast<SCALAR>(i));
|
||||
}
|
||||
|
||||
// Each work-item writes its global id to output[work-item-global-id]
|
||||
std::string generate_program()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
#if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
return
|
||||
"__kernel void " + this->get_kernel_name() + "(global " + type_name<T>() + " *output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = (" + type_name<T>() + ")(gid);\n"
|
||||
"}\n";
|
||||
|
||||
#else
|
||||
return
|
||||
"#include <opencl_memory>\n"
|
||||
"#include <opencl_work_item>\n"
|
||||
"#include <opencl_array>\n"
|
||||
"using namespace cl;\n"
|
||||
"__kernel void " + this->get_kernel_name() + "(global_ptr<" + type_name<T>() + "[]> output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" typedef " + type_name<T>() + " TYPE;\n"
|
||||
" priv<TYPE> v = { TYPE(gid) };\n"
|
||||
" const TYPE *v_ptr1 = &v;\n"
|
||||
" private_ptr<TYPE> v_ptr2 = v.ptr();\n"
|
||||
" TYPE v2 = *v_ptr2;\n"
|
||||
" priv<array<TYPE, 1>> a;\n"
|
||||
" *(a.begin()) = v2;\n"
|
||||
" output[gid] = a[0];\n"
|
||||
"}\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
AUTO_TEST_CASE(test_private_storage)
|
||||
(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
int last_error = CL_SUCCESS;
|
||||
|
||||
// private storage
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_storage_test<cl_uint>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_storage_test<cl_float2>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_storage_test<cl_float4>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_storage_test<cl_float8>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(private_storage_test<cl_uint16>());
|
||||
|
||||
if(error != CL_SUCCESS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// ---------- LOCAL
|
||||
// ----------------------------
|
||||
|
||||
template <class T>
|
||||
struct local_storage_test : public address_spaces_test<T>
|
||||
{
|
||||
std::string str()
|
||||
{
|
||||
return "local_storage";
|
||||
}
|
||||
|
||||
T operator()(size_t i, size_t work_group_size)
|
||||
{
|
||||
typedef typename scalar_type<T>::type SCALAR;
|
||||
size_t r = i / work_group_size;
|
||||
return detail::make_value<T>(static_cast<SCALAR>(r));
|
||||
}
|
||||
|
||||
bool set_local_size()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Every work-item writes id of its work-group to output[work-item-global-id]
|
||||
std::string generate_program()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
#if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
return
|
||||
"__kernel void " + this->get_kernel_name() + "(global " + type_name<T>() + " *output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = (" + type_name<T>() + ")(get_group_id(0));\n"
|
||||
"}\n";
|
||||
|
||||
#else
|
||||
return
|
||||
"#include <opencl_memory>\n"
|
||||
"#include <opencl_work_item>\n"
|
||||
"#include <opencl_synchronization>\n"
|
||||
"#include <opencl_array>\n"
|
||||
"using namespace cl;\n"
|
||||
// Using program scope local variable
|
||||
"local<" + type_name<T>() + "> program_scope_var;"
|
||||
"__kernel void " + this->get_kernel_name() + "(global_ptr<" + type_name<T>() + "[]> output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" size_t lid = get_local_id(0);\n"
|
||||
" typedef " + type_name<T>() + " TYPE;\n"
|
||||
// 1st work-item in work-group writes get_group_id() to var
|
||||
" local<TYPE> var;\n"
|
||||
" if(lid == 0) { var = TYPE(get_group_id(0)); }\n"
|
||||
" work_group_barrier(mem_fence::local);\n"
|
||||
// last work-item in work-group writes var to 1st element of a
|
||||
" local_ptr<TYPE> var_ptr = var.ptr();\n"
|
||||
" TYPE var2 = *var_ptr;\n"
|
||||
" local<array<TYPE, 1>> a;\n"
|
||||
" if(lid == (get_local_size(0) - 1)) { *(a.begin()) = var2; }\n"
|
||||
" work_group_barrier(mem_fence::local);\n"
|
||||
// 1st work-item in work-group writes a[0] to program_scope_var
|
||||
" if(lid == 0) { program_scope_var = a[0]; }\n"
|
||||
" work_group_barrier(mem_fence::local);\n"
|
||||
" const TYPE *program_scope_var_ptr = &program_scope_var;\n"
|
||||
" output[gid] = *program_scope_var_ptr;\n"
|
||||
"}\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
AUTO_TEST_CASE(test_local_storage)
|
||||
(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
int last_error = CL_SUCCESS;
|
||||
|
||||
// local storage
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_storage_test<cl_uint>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_storage_test<cl_float2>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_storage_test<cl_float4>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_storage_test<cl_float8>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(local_storage_test<cl_int16>());
|
||||
|
||||
if(error != CL_SUCCESS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// ---------- GLOBAL
|
||||
// ----------------------------
|
||||
|
||||
template <class T>
|
||||
struct global_storage_test : public address_spaces_test<T>
|
||||
{
|
||||
// m_test_value is just a random value we use in this test.
|
||||
// m_test_value should not be zero.
|
||||
global_storage_test() : m_test_value(0xdeaddeadU)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string str()
|
||||
{
|
||||
return "global_storage";
|
||||
}
|
||||
|
||||
T operator()(size_t i, size_t work_group_size)
|
||||
{
|
||||
typedef typename scalar_type<T>::type SCALAR;
|
||||
return detail::make_value<T>(static_cast<SCALAR>(m_test_value));
|
||||
}
|
||||
|
||||
std::vector<std::string> get_kernel_names()
|
||||
{
|
||||
return
|
||||
{
|
||||
this->get_kernel_name() + "1",
|
||||
this->get_kernel_name() + "2"
|
||||
};
|
||||
}
|
||||
|
||||
// Every work-item writes m_test_value to output[work-item-global-id]
|
||||
std::string generate_program()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
#if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
return
|
||||
"__kernel void " + this->get_kernel_names()[0] + "(global " + type_name<T>() + " *output, "
|
||||
"uint test_value)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = (" + type_name<T>() + ")(test_value);\n"
|
||||
"}\n"
|
||||
"__kernel void " + this->get_kernel_names()[1] + "(global " + type_name<T>() + " *output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = output[gid];\n"
|
||||
"}\n";
|
||||
#else
|
||||
return
|
||||
"#include <opencl_memory>\n"
|
||||
"#include <opencl_work_item>\n"
|
||||
"#include <opencl_array>\n"
|
||||
"using namespace cl;\n"
|
||||
"typedef " + type_name<T>() + " TYPE;\n"
|
||||
// Using program scope global variable
|
||||
"global<array<TYPE, 1>> program_scope_global_array;"
|
||||
"__kernel void " + this->get_kernel_names()[0] + "(global_ptr<" + type_name<T>() + "[]> output, "
|
||||
"uint test_value)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
// 1st work-item writes test_value to program_scope_global_array[0]
|
||||
" if(gid == 0) { program_scope_global_array[0] = test_value; }\n"
|
||||
"}\n"
|
||||
"__kernel void " + this->get_kernel_names()[1] + "(global_ptr<" + type_name<T>() + "[]> output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" static global<uint> func_scope_global_var { 0 };\n"
|
||||
// if (func_scope_global_var == 1) is true then
|
||||
// each work-item saves program_scope_global_array[0] to output[work-item-global-id]
|
||||
" if(func_scope_global_var == uint(1))\n"
|
||||
" {\n"
|
||||
" output[gid] = program_scope_global_array[0];\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
// 1st work-item writes 1 to func_scope_global_var
|
||||
" if(gid == 0) { func_scope_global_var = uint(1); }\n"
|
||||
"}\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
// In this test execution is quite complicated. We have two kernels.
|
||||
// 1st kernel tests program scope global variable, and 2nd kernel tests
|
||||
// function scope global variable (that's why it is run twice).
|
||||
cl_int execute(const std::vector<cl_kernel>& kernels,
|
||||
cl_mem& output_buffer,
|
||||
cl_command_queue& queue,
|
||||
size_t work_size,
|
||||
size_t wg_size)
|
||||
{
|
||||
cl_int err;
|
||||
err = clSetKernelArg(kernels[0], 0, sizeof(output_buffer), &output_buffer);
|
||||
err |= clSetKernelArg(kernels[0], 1, sizeof(cl_uint), &m_test_value);
|
||||
RETURN_ON_CL_ERROR(err, "clSetKernelArg");
|
||||
|
||||
// Run first kernel, once.
|
||||
// This kernel saves m_test_value to program scope global variable called program_scope_global_var
|
||||
err = clEnqueueNDRangeKernel(
|
||||
queue, kernels[0], 1, NULL, &work_size, this->set_local_size() ? &wg_size : NULL, 0, NULL, NULL
|
||||
);
|
||||
RETURN_ON_CL_ERROR(err, "clEnqueueNDRangeKernel");
|
||||
err = clFinish(queue);
|
||||
RETURN_ON_CL_ERROR(err, "clFinish")
|
||||
|
||||
err = clSetKernelArg(kernels[1], 0, sizeof(output_buffer), &output_buffer);
|
||||
// Run 2nd kernel, twice.
|
||||
// 1st run: program_scope_global_var is saved to function scope global array called func_scope_global_array
|
||||
// 2nd run: each work-item saves func_scope_global_array[0] to ouput[work-item-global-id]
|
||||
for(size_t i = 0; i < 2; i++)
|
||||
{
|
||||
err = clEnqueueNDRangeKernel(
|
||||
queue, kernels[1], 1, NULL, &work_size, this->set_local_size() ? &wg_size : NULL, 0, NULL, NULL
|
||||
);
|
||||
RETURN_ON_CL_ERROR(err, "clEnqueueNDRangeKernel");
|
||||
err = clFinish(queue);
|
||||
RETURN_ON_CL_ERROR(err, "clFinish")
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
private:
|
||||
cl_uint m_test_value;
|
||||
};
|
||||
|
||||
AUTO_TEST_CASE(test_global_storage)
|
||||
(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
int last_error = CL_SUCCESS;
|
||||
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_storage_test<cl_uint>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_storage_test<cl_float2>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_storage_test<cl_float4>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_storage_test<cl_float8>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(global_storage_test<cl_int16>());
|
||||
|
||||
if(error != CL_SUCCESS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// ---------- CONSTANT
|
||||
// ----------------------------
|
||||
|
||||
template <class T>
|
||||
struct constant_storage_test : public address_spaces_test<T>
|
||||
{
|
||||
// m_test_value is just a random value we use in this test.
|
||||
constant_storage_test() : m_test_value(0xdeaddeadU)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string str()
|
||||
{
|
||||
return "constant_storage";
|
||||
}
|
||||
|
||||
T operator()(size_t i, size_t work_group_size)
|
||||
{
|
||||
typedef typename scalar_type<T>::type SCALAR;
|
||||
return detail::make_value<T>(static_cast<SCALAR>(m_test_value));
|
||||
}
|
||||
|
||||
// Every work-item writes m_test_value to output[work-item-global-id]
|
||||
std::string generate_program()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
#if defined(DEVELOPMENT) && defined(USE_OPENCLC_KERNELS)
|
||||
return
|
||||
"__kernel void " + this->get_kernel_name() + "(global " + type_name<T>() + " *output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" output[gid] = (" + type_name<T>() + ")(" + std::to_string(m_test_value) + ");\n"
|
||||
"}\n";
|
||||
|
||||
#else
|
||||
return
|
||||
"#include <opencl_memory>\n"
|
||||
"#include <opencl_work_item>\n"
|
||||
"#include <opencl_array>\n"
|
||||
"using namespace cl;\n"
|
||||
// Program scope constant variable, program_scope_var == (m_test_value - 1)
|
||||
"constant<uint> program_scope_const{ (" + std::to_string(m_test_value) + " - 1) };"
|
||||
"__kernel void " + this->get_kernel_name() + "(global_ptr<" + type_name<T>() + "[]> output)\n"
|
||||
"{\n"
|
||||
" size_t gid = get_global_id(0);\n"
|
||||
" typedef " + type_name<T>() + " TYPE;\n"
|
||||
" static constant<uint> func_scope_const{ 1 };\n"
|
||||
" constant_ptr<uint> ps_const_ptr = program_scope_const.ptr();\n"
|
||||
// " constant_ptr<array<uint, 1>> fs_const_ptr = &func_scope_const;\n"
|
||||
" output[gid] = TYPE(*ps_const_ptr + func_scope_const);\n"
|
||||
"}\n";
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
cl_uint m_test_value;
|
||||
};
|
||||
|
||||
AUTO_TEST_CASE(test_constant_storage)
|
||||
(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
int last_error = CL_SUCCESS;
|
||||
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_storage_test<cl_uint>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_storage_test<cl_float2>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_storage_test<cl_float4>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_storage_test<cl_float8>());
|
||||
RUN_ADDRESS_SPACES_TEST_MACRO(constant_storage_test<cl_int16>());
|
||||
|
||||
if(error != CL_SUCCESS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // TEST_CONFORMANCE_CLCPP_ADDRESS_SPACES_TEST_STORAGE_TYPES_HPP
|
||||
Reference in New Issue
Block a user