Skip to content

Commit

Permalink
[SYCL][CUDA] Image Basic Test (#1970)
Browse files Browse the repository at this point in the history
Provides new generic testing for SYCL image functionality.
  • Loading branch information
nyalloc authored Oct 12, 2020
1 parent 4644e63 commit 304067c
Show file tree
Hide file tree
Showing 10 changed files with 818 additions and 7 deletions.
3 changes: 0 additions & 3 deletions sycl/test/basic_tests/image.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// UNSUPPORTED: cuda
// CUDA cannot support SYCL 1.2.1 images.
//
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
Expand Down
28 changes: 28 additions & 0 deletions sycl/test/basic_tests/image/image_read.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %GPU_RUN_PLACEHOLDER %t.out

#include "image_read.h"

int main() {

s::default_selector selector;
s::queue myQueue(selector);

bool passed = true;

// Float image
if (!test<s::float4, s::image_channel_type::fp32>(myQueue))
passed = false;

// 32-bit signed integer image
if (!test<s::int4, s::image_channel_type::signed_int32>(myQueue))
passed = false;

// 32-bit unsigned integer image
if (!test<s::uint4, s::image_channel_type::unsigned_int32>(myQueue))
passed = false;

return passed ? 0 : -1;
}
235 changes: 235 additions & 0 deletions sycl/test/basic_tests/image/image_read.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
/**
* Tests clamp_to_edge addressing mode with nearest and linear filtering modes
* on a 4x4 image.
*
* Expected addressing mode and filtering results are given by the algorithm in
* the OpenCL 1.2 specification, Section 8. Image Addressing and Filtering
*
* https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf#page=329
*
* Confirmed to pass with -fsycl-targets=spir64-unknown-linux-sycldevice
*/

#include <CL/sycl.hpp>

#include <iostream>

template <typename T> class test_1d_class;
template <typename T> class test_2d_class;
template <typename T> class test_3d_class;

namespace s = cl::sycl;

template <typename dataT, typename coordT, s::image_channel_type channelType>
bool test1d_coord(s::queue myQueue, dataT *hostPtr, coordT coord,
dataT expectedColour) {
dataT resultData;

{ // Scope everything to force destruction
s::image<1> image(hostPtr, s::image_channel_order::rgba, channelType,
s::range<1>{3});

s::buffer<dataT, 1> resultDataBuf(&resultData, s::range<1>(1));

// Do the test by reading a single pixel from the image
myQueue.submit([&](s::handler &cgh) {
auto imageAcc = image.get_access<dataT, s::access::mode::read>(cgh);
s::accessor<dataT, 1, s::access::mode::write> resultDataAcc(resultDataBuf,
cgh);

cgh.single_task<test_1d_class<dataT>>([=]() {
dataT RetColor = imageAcc.read(coord);
resultDataAcc[0] = RetColor;
});
});
}
#ifdef DEBUG_OUTPUT
std::cout << "Expected: " << expectedColour.r() << ", " << expectedColour.g()
<< ", " << expectedColour.b() << ", " << expectedColour.a() << "\n";
std::cout << "Got: " << resultData.r() << ", " << resultData.g() << ", "
<< resultData.b() << ", " << resultData.a() << "\n";
#endif // DEBUG_OUTPUT
bool correct = true;
if (resultData.r() != expectedColour.r())
correct = false;
if (resultData.g() != expectedColour.g())
correct = false;
if (resultData.b() != expectedColour.b())
correct = false;
if (resultData.a() != expectedColour.a())
correct = false;
return correct;
}

template <typename dataT, typename coordT, s::image_channel_type channelType>
bool test2d_coord(s::queue myQueue, dataT *hostPtr, coordT coord,
dataT expectedColour) {
dataT resultData;

{ // Scope everything to force destruction
s::image<2> image(hostPtr, s::image_channel_order::rgba, channelType,
s::range<2>{3, 3});

s::buffer<dataT, 1> resultDataBuf(&resultData, s::range<1>(1));

// Do the test by reading a single pixel from the image
myQueue.submit([&](s::handler &cgh) {
auto imageAcc = image.get_access<dataT, s::access::mode::read>(cgh);
s::accessor<dataT, 1, s::access::mode::write> resultDataAcc(resultDataBuf,
cgh);

cgh.single_task<test_2d_class<dataT>>([=]() {
dataT RetColor = imageAcc.read(coord);
resultDataAcc[0] = RetColor;
});
});
}

#ifdef DEBUG_OUTPUT
std::cout << "Got: " << resultData.r() << ", " << resultData.g();
#endif // DEBUG_OUTPUT

bool correct = true;
if (resultData.r() != expectedColour.r())
correct = false;
if (resultData.g() != expectedColour.g())
correct = false;
if (resultData.b() != expectedColour.b())
correct = false;
if (resultData.a() != expectedColour.a())
correct = false;
return correct;
}

template <typename dataT, typename coordT, s::image_channel_type channelType>
bool test3d_coord(s::queue myQueue, dataT *hostPtr, coordT coord,
dataT expectedColour) {
dataT resultData;

{ // Scope everything to force destruction
s::image<3> image(hostPtr, s::image_channel_order::rgba, channelType,
s::range<3>{3, 3, 3});

s::buffer<dataT, 1> resultDataBuf(&resultData, s::range<1>(1));

// Do the test by reading a single pixel from the image
myQueue.submit([&](s::handler &cgh) {
auto imageAcc = image.get_access<dataT, s::access::mode::read>(cgh);
s::accessor<dataT, 1, s::access::mode::write> resultDataAcc(resultDataBuf,
cgh);

cgh.single_task<test_3d_class<dataT>>([=]() {
dataT RetColor = imageAcc.read(coord);
resultDataAcc[0] = RetColor;
});
});
}
#ifdef DEBUG_OUTPUT
std::cout << "Expected: " << expectedColour.r() << ", " << expectedColour.g()
<< ", " << expectedColour.b() << ", " << expectedColour.a() << "\n";
std::cout << "Got: " << resultData.r() << ", " << resultData.g() << ", "
<< resultData.b() << ", " << resultData.a() << "\n";
#endif // DEBUG_OUTPUT
bool correct = true;
if (resultData.r() != expectedColour.r())
correct = false;
if (resultData.g() != expectedColour.g())
correct = false;
if (resultData.b() != expectedColour.b())
correct = false;
if (resultData.a() != expectedColour.a())
correct = false;
return correct;
}

template <typename dataT, typename coordT, s::image_channel_type channelType>
bool test1d(s::queue myQueue, coordT coord, dataT expectedResult) {
dataT hostPtr[3];
for (int i = 0; i < 3; i++)
hostPtr[i] = dataT(0 + i, 20 + i, 40 + i, 60 + i);

return test1d_coord<dataT, coordT, channelType>(myQueue, hostPtr, coord,
expectedResult);
}

template <typename dataT, typename coordT, s::image_channel_type channelType>
bool test2d(s::queue myQueue, coordT coord, dataT expectedResult) {
dataT hostPtr[9];
for (int i = 0; i < 9; i++)
hostPtr[i] = dataT(0 + i, 20 + i, 40 + i, 60 + i);

return test2d_coord<dataT, coordT, channelType>(myQueue, hostPtr, coord,
expectedResult);
}

template <typename dataT, typename coordT, s::image_channel_type channelType>
bool test3d(s::queue myQueue, coordT coord, dataT expectedResult) {
dataT hostPtr[27];
for (int i = 0; i < 27; i++)
hostPtr[i] = dataT(0 + i, 20 + i, 40 + i, 60 + i);

return test3d_coord<dataT, coordT, channelType>(myQueue, hostPtr, coord,
expectedResult);
}

template <typename dataT, s::image_channel_type channelType>
bool test(s::queue myQueue) {
bool passed = true;
// 1d image tests
if (!test1d<dataT, int, channelType>(myQueue, 0, dataT(0, 20, 40, 60)))
passed = false;

if (!test1d<dataT, int, channelType>(myQueue, 1, dataT(1, 21, 41, 61)))
passed = false;

if (!test1d<dataT, int, channelType>(myQueue, 2, dataT(2, 22, 42, 62)))
passed = false;

// 2d image tests
if (!test2d<dataT, s::int2, channelType>(myQueue, s::int2(0, 0),
dataT(0, 20, 40, 60)))
passed = false;

if (!test2d<dataT, s::int2, channelType>(myQueue, s::int2(1, 0),
dataT(1, 21, 41, 61)))
passed = false;

if (!test2d<dataT, s::int2, channelType>(myQueue, s::int2(0, 1),
dataT(3, 23, 43, 63)))
passed = false;

if (!test2d<dataT, s::int2, channelType>(myQueue, s::int2(1, 1),
dataT(4, 24, 44, 64)))
passed = false;

// 3d image tests
if (!test3d<dataT, s::int4, channelType>(myQueue, s::int4(0, 0, 0, 0),
dataT(0, 20, 40, 60)))
passed = false;

if (!test3d<dataT, s::int4, channelType>(myQueue, s::int4(1, 0, 0, 0),
dataT(1, 21, 41, 61)))
passed = false;

if (!test3d<dataT, s::int4, channelType>(myQueue, s::int4(0, 1, 0, 0),
dataT(3, 23, 43, 63)))
passed = false;

if (!test3d<dataT, s::int4, channelType>(myQueue, s::int4(1, 1, 0, 0),
dataT(4, 24, 44, 64)))
passed = false;

if (!test3d<dataT, s::int4, channelType>(myQueue, s::int4(1, 0, 1, 0),
dataT(10, 30, 50, 70)))
passed = false;

if (!test3d<dataT, s::int4, channelType>(myQueue, s::int4(0, 1, 1, 0),
dataT(12, 32, 52, 72)))
passed = false;

if (!test3d<dataT, s::int4, channelType>(myQueue, s::int4(1, 1, 1, 0),
dataT(13, 33, 53, 73)))
passed = false;

return passed;
}
21 changes: 21 additions & 0 deletions sycl/test/basic_tests/image/image_read_fp16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %GPU_RUN_PLACEHOLDER %t.out

#include "image_read.h"

int main() {
s::default_selector selector;
s::queue myQueue(selector);

// Device doesn't support cl_khr_fp16 extension - skip.
if (!myQueue.get_device().has_extension("cl_khr_fp16"))
return 0;

// Half image
if (!test<s::half4, s::image_channel_type::fp16>(myQueue))
return -1;

return 0;
}
Loading

0 comments on commit 304067c

Please sign in to comment.