#include <mutex>
#include <unordered_map>
#include "common/c_types_map.hpp"
#include "common/utils.hpp"
#include "gpu/intel/compute/kernel.hpp"
#include "gpu/intel/compute/kernel_ctx.hpp"
#include "gpu/intel/engine.hpp"
#include "gpu/intel/stream.hpp"
namespace dnnl {
namespace impl {
namespace gpu {
namespace intel {
static status_t get_cached_kernel(
intel::engine_t *engine, compute::kernel_t &kernel) {
static std::unordered_map<engine_id_t, compute::kernel_t> cache;
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
auto it = cache.find(engine->engine_id());
if (it != cache.end()) {
kernel = it->second;
return status::success;
}
compute::kernel_ctx_t ctx;
std::vector<compute::kernel_t> kernels;
CHECK(engine->create_kernels(&kernels, {"fill_random"}, ctx));
kernel = cache.emplace(engine->engine_id(), kernels[0]).first->second;
return status::success;
}
status_t fill_random(impl::stream_t *stream, size_t size,
impl::memory_t *memory, int buffer_index, uint32_t seed) {
if (size == 0) return status::success;
auto *intel_stream = utils::downcast<intel::stream_t *>(stream);
auto *intel_engine = utils::downcast<intel::engine_t *>(stream->engine());
compute::kernel_t kernel;
CHECK(get_cached_kernel(intel_engine, kernel));
static constexpr size_t subgroup_size = 16;
static constexpr size_t bytes_per_subgroup
= subgroup_size * 4 * sizeof(uint32_t);
size_t num_subgroups = utils::div_up(size, bytes_per_subgroup);
compute::nd_range_t nd_range({num_subgroups * subgroup_size, 1, 1});
compute::kernel_arg_list_t arg_list;
arg_list.set(0, *memory->memory_storage(buffer_index));
arg_list.set(1, seed);
arg_list.set(2, static_cast<uint64_t>(size));
CHECK(kernel.parallel_for(*stream, nd_range, arg_list,
intel_stream->ctx().get_deps(), intel_stream->ctx().get_deps()));
return status::success;
}
} } } }
extern "C" dnnl::impl::status_t DNNL_API dnnl_impl_gpu_fill_random(
dnnl::impl::stream_t *stream, size_t size, dnnl::impl::memory_t *memory,
int buffer_index, uint32_t seed) {
return dnnl::impl::gpu::intel::fill_random(
stream, size, memory, buffer_index, seed);
}