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

Add new test for get_pointer_type and get_pointer_device USM API #131

Merged
merged 6 commits into from Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
83 changes: 83 additions & 0 deletions tests/usm/usm.h
@@ -0,0 +1,83 @@
/*******************************************************************************
//
// SYCL 2020 Conformance Test Suite
//
// Common code for USM tests
//
*******************************************************************************/

#ifndef __SYCL_CTS_TEST_USM_USM_H
#define __SYCL_CTS_TEST_USM_USM_H

#include "../common/common.h"
#include <memory>
#include <string_view>

namespace usm {

/** @brief Return std::unique_ptr with allocated USM object
* @tparam USM allocation type
* @param queue sycl::queue class object
*/
template <sycl::usm::alloc alloc, typename elems_typeT>
auto allocate_usm_memory(const sycl::queue &queue, size_t num_elements = 1) {
const auto &device{queue.get_device()};
const auto &context{queue.get_context()};

auto deleter = [=](elems_typeT *ptr) { sycl::free(ptr, context); };

if constexpr (alloc == sycl::usm::alloc::shared) {
std::unique_ptr<elems_typeT, decltype(deleter)> usm_memory(
sycl::malloc_shared<elems_typeT>(num_elements, device, context),
deleter);
return usm_memory;
} else if constexpr (alloc == sycl::usm::alloc::device) {
std::unique_ptr<elems_typeT, decltype(deleter)> usm_memory(
sycl::malloc_device<elems_typeT>(num_elements, queue), deleter);
return usm_memory;
} else if constexpr (alloc == sycl::usm::alloc::host) {
std::unique_ptr<elems_typeT, decltype(deleter)> usm_memory(
sycl::malloc_host<elems_typeT>(num_elements, context), deleter);
return usm_memory;
} else {
static_assert(alloc != alloc, "Unknown USM allocation type");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this to have a dependent static_assert to avoid triggering with false independently from the if constexpr?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i correctly understood you.
We using static_assert here to interrupt compilation if test developer try to allocate memory from non USM allocation type (here we using all available allocation types from SYCL2020 spec section #4.8.2. "Kinds of unified shared memory")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question was about

static_assert(false, "Unknown USM allocation type");

that you cannot probably use?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that good decision, thanks for your advice
This change was made in: 684a2ec

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@keryell @vasilytric I assume 684a2ec will break compilation due non-conditional static_assert. See SO thread for details

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@keryell Yes, static_assert(false, "Unknown USM allocation type"); cannot be used

}
};

/** @brief Returns an aspect depending on the type of allocated memory
* @tparam alloc USM allocation type
* @retval SYCL aspect that corresponds to allocated memory
*/
template <const sycl::usm::alloc alloc>
constexpr auto get_aspect() {
if constexpr (alloc == sycl::usm::alloc::shared) {
return sycl::aspect::usm_shared_allocations;
} else if constexpr (alloc == sycl::usm::alloc::device) {
return sycl::aspect::usm_device_allocations;
} else if constexpr (alloc == sycl::usm::alloc::host) {
return sycl::aspect::usm_host_allocations;
} else {
static_assert(alloc != alloc, "Unknown USM allocation type");
}
}

/** @brief Return string's description depending on the type of allocated memory
* @tparam alloc USM allocation type
* @retval String description of allocated memory
*/
template <sycl::usm::alloc alloc>
std::string_view get_allocation_description() {
vasilytric marked this conversation as resolved.
Show resolved Hide resolved
if constexpr (alloc == sycl::usm::alloc::shared) {
return "shared";
} else if constexpr (alloc == sycl::usm::alloc::device) {
return "device";
} else if constexpr (alloc == sycl::usm::alloc::host) {
return "host";
} else {
static_assert(alloc != alloc, "Unknown USM allocation type");
}
}

} // namespace usm

#endif // __SYCL_CTS_TEST_USM_USM_H
11 changes: 3 additions & 8 deletions tests/usm/usm_fill_memset_memcpy.cpp
Expand Up @@ -6,7 +6,7 @@
//
*******************************************************************************/

#include "../common/common.h"
#include "usm.h"
#include <cstring>

#define TEST_NAME usm_fill_memset_memcpy
Expand Down Expand Up @@ -41,13 +41,8 @@ class TEST_NAME : public sycl_cts::util::test_base {
constexpr auto value_for_filling{1};
constexpr auto value_for_first_element_overwriting{10};

auto deleter = [&q](int *data) { sycl::free(data, q.get_context()); };
std::unique_ptr<int, decltype(deleter)> src(
sycl::malloc_shared<int>(size, q.get_device(), q.get_context()),
deleter);
std::unique_ptr<int, decltype(deleter)> output(
sycl::malloc_shared<int>(size, q.get_device(), q.get_context()),
deleter);
auto src {usm::allocate_usm_memory<sycl::usm::alloc::shared, int>(q, count)};
auto output {usm::allocate_usm_memory<sycl::usm::alloc::shared, int>(q, count)};

sycl::event init_fill = q.submit([&](sycl::handler &cgh) {
cgh.fill(src.get(), value_for_filling, count);
Expand Down
87 changes: 87 additions & 0 deletions tests/usm/usm_get_pointer_queries.cpp
@@ -0,0 +1,87 @@
/*******************************************************************************
//
// SYCL 2020 Conformance Test Suite
//
// Provide verification to cooperation USM functions get_pointer_type and
// get_pointer_device with four memory allocation types: host, device, shared
// and non USM allocation.
//
*******************************************************************************/

#include "usm.h"
#include <cstring>

#define TEST_NAME usm_get_pointer_queries

namespace TEST_NAMESPACE {
using namespace sycl_cts;

template <sycl::usm::alloc alloc>
void run_check(const sycl::queue &queue, sycl_cts::util::logger &log) {
const auto &device{queue.get_device()};
const auto &context{queue.get_context()};

auto str_usm_alloc_type{usm::get_allocation_description<alloc>()};

if (device.has(usm::get_aspect<alloc>())) {
auto allocated_memory = usm::allocate_usm_memory<alloc, int>(queue);
const auto value = sycl::get_pointer_type(allocated_memory.get(), context);

if (alloc != value) {
FAIL(log, "sycl::get_pointer_type return " +
std::to_string(to_integral(value)) +
" type, expected sycl::usm::alloc::" +
std::string(str_usm_alloc_type) + " type");
}
if (sycl::get_pointer_device(allocated_memory.get(), context) != device) {
FAIL(log, "sycl::get_pointer_device return invalid device for " +
std::string(str_usm_alloc_type) + " type");
}
} else {
log.note("Device does not support " + std::string(str_usm_alloc_type) +
" allocation. Tests were skipped.");
}
}

/** Test instance
*/
class TEST_NAME : public sycl_cts::util::test_base {
public:
/** return information about this test
*/
void get_info(test_base::info &out) const override {
set_test_info(out, TOSTRING(TEST_NAME), TEST_FILE);
}

/** execute the test
*/
void run(util::logger &log) override {
try {
auto queue{util::get_cts_object::queue()};

{
int non_usm_allocated_memory{};
if (sycl::usm::alloc::unknown !=
sycl::get_pointer_type(&non_usm_allocated_memory,
queue.get_context())) {
FAIL(log,
"sycl::get_pointer_type return not sycl::usm::alloc::unknown "
"type");
}
}

run_check<sycl::usm::alloc::shared>(queue, log);
run_check<sycl::usm::alloc::device>(queue, log);
run_check<sycl::usm::alloc::host>(queue, log);

} catch (const cl::sycl::exception &e) {
log_exception(log, e);
auto errorMsg = "a SYCL exception was caught: " + std::string(e.what());
FAIL(log, errorMsg);
}
}
};

// construction of this proxy will register the above test
util::test_proxy<TEST_NAME> proxy;
} // namespace TEST_NAMESPACE