We provide in include/tools/usm_smart_ptr.hpp overloads to std::unique_ptr and std::shared_ptr that manages SYCL's USM memory.
using namespace usm_smart_ptr;
sbb::queue q;
size_t count;
auto usm_unique_ptr = make_unique_ptr<my_type, alloc::shared>(count, q); // could return a pointer to sbb::malloc_shared<my_type>(count, q);
auto usm_shared_ptr = make_shared_ptr<my_type, alloc::shared>(count, q);You can choose between alloc::device, alloc::shared and alloc::host. Calling .get() on the pointers will return a decorated pointer to the underlying memory which allow to keep track of where the memory was
allocated. It's just compile-time type safety. These decorated types allow to further construct the types :
device_accessible_ptr<byte>host_accessible_ptr<byte>
This prevents the following (potentially incorrect) code from compiling:
// A function
void fill_on_host(host_accessible_ptr<flloat> ptr, size_t size){
float* raw_ptr = (float*) ptr;
//do your thing on the host
}
// later
auto device_memory = make_shared_ptr<flloat, alloc::device>(1024, q);
// attempt to fill the memory
fill_on_host(device_memory.get(), 1024); // Won't compile, we're saved!The number of inputs and template arguments to the hashing function depends on the type. Any missing or extra argument passed will result in compilation failure.
hash::compute<hash::method::blake2b, n_outbit>(queue, input_ptr, input_block_size, output_hashes, n_blocs, key_ptr, key_size);
hash::compute<hash::method::keccak, n_outbit>(queue, input_ptr, input_block_size, output_hashes, n_blocs);
hash::compute<hash::method::sha3, n_outbit>(queue, input_ptr, input_block_size, output_hashes, n_blocs;
hash::compute<hash::method::sha1>(queue, input_ptr, input_block_size, output_hashes, n_blocs,);
hash::compute<hash::method::sha256>(queue, input_ptr, input_block_size, output_hashes, n_blocs);
hash::compute<hash::method::md2>(queue, input_ptr, input_block_size, output_hashes, n_blocs);
hash::compute<hash::method::md5>(queue, input_ptr, input_block_size, output_hashes, n_blocs);We'll consider the blake2b method in the rest. For each method we got two overloads :
hash::compute<hash::method::blake2b, n_outbit>(sbb::queue &q, const byte*, dword, byte*, dword, byte *, dword);
This is the overload you would call if you got C++ allocated pointers to your memory (array on the stack, malloc, new[], ...). When calling this function, the memory will be copied behind the scenes to the device as it's the safets behaviour.
If you wrap your memory pointers in device_accessible_ptr<byte> (see include/tools/usm_smart_ptr.hpp), then the library will assume these points to a memory that is accessible by the sbb::device you build
your sbb::queue on.
hash::compute<hash::method::blake2b, n_outbit>(sbb::queue &q, const device_accessible_ptr<byte>, dword, device_accessible_ptr<byte>, dword, const byte *, dword);
Best, this overload will be called if you use the previously described usm_smart_ptr wrappers with alloc::device or alloc::shared. We voluntarily excluded alloc::host as the remote memory accesses could
potentially cause performanec issues.
The following constexpr function returns the length, in bytes of a hash produced by the method.
hash::get_block_size<hash::method::keccak, 128>();You can also query the name with:
hash::get_name<hash::method::keccak, 128>()r
The nd_range sizes are computed in include/determine_kernel_config.hpp. When running on a CPU we'll try to make twice as much work groups as you've got execution threads on your system as, with OpenCL, each work group
seems to be executed on one CPU thread. When running on the GPU we'll try to make work groups that contains 64 work items each. Going above 64 seems to decrease performance. This behaviour might not be optimal and should
be customised to fit your SYCL implementation.