Skip to content

Commit

Permalink
OpenCL kernel runners
Browse files Browse the repository at this point in the history
  • Loading branch information
Pencilcaseman committed Mar 30, 2024
1 parent 4d6bb48 commit 918da5b
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 37 deletions.
8 changes: 3 additions & 5 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,13 @@ fn main() {
builder = builder.header("./hasty_impl/include/helper/define_opencl.h");
}

builder = builder // .header("./hasty_impl/include/hasty_impl.h")
// .clang_arg("-I./hasty_impl/include")
// .header("./hasty_impl/include/hasty_blas.h")
builder = builder
.header("./hasty_impl/include/level2/gemv.h")
.header("./hasty_impl/include/level3/gemm.h")
// .header("./hasty_impl/include/hasty_opencl.h")
.header("./hasty_impl/include/opencl/opencl_error_types.h")
.header("./hasty_impl/include/opencl/opencl_configure.h")
.header("./hasty_impl/include/opencl/opencl_memory_impl.h");
.header("./hasty_impl/include/opencl/opencl_memory_impl.h")
.header("./hasty_impl/include/opencl/opencl_kernel_impl.h");

let bindings = builder
.generate()
Expand Down
2 changes: 2 additions & 0 deletions hasty_impl/include/opencl/opencl_global.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace global {
extern cl::Device openCLDevice;
extern cl::Context openCLContext;
extern cl::CommandQueue openCLQueue;
extern cl::Program::Sources openCLSources;
extern cl::Program openCLProgram;
}

#endif // HASTY_IMPL_HAS_OPENCL
Expand Down
33 changes: 33 additions & 0 deletions hasty_impl/include/opencl/opencl_kernel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef HASTY_IMPL_OPENCL_KERNEL_HPP
#define HASTY_IMPL_OPENCL_KERNEL_HPP
#ifdef HASTY_IMPL_HAS_OPENCL

#include <iostream>

#include "./opencl.hpp"
#include "./opencl_error_types.h"
#include "./opencl_errors.hpp"
#include "./opencl_global.hpp"
#include "./opencl_memory_impl.h"

OpenCLErrorCode opencl_add_kernel(const std::string &kernelSource);

template<size_t... I, typename... Args>
void setKernelArgs(cl::Kernel &kernel, const std::tuple<Args...> &args,
std::index_sequence<I...>, size_t offset = 0) {
((kernel.setArg(I + offset, std::get<I>(args))), ...);
}

template<typename... Args>
OpenCLErrorCode
opencl_run_contiguous_linear_kernel(const std::string &kernelName, size_t numElements,
Args... args) {
// std::cout << "Running kernel " << kernelName << " with " << numElements << " elements\n";
cl::Kernel kernel(global::openCLProgram, kernelName.c_str());
setKernelArgs(kernel, std::make_tuple(args...), std::make_index_sequence<sizeof...(Args)>());
cl::NDRange range(numElements);
return get_opencl_error_code(global::openCLQueue.enqueueNDRangeKernel(kernel, cl::NullRange, range, cl::NullRange));
}

#endif // HASTY_IMPL_HAS_OPENCL
#endif //HASTY_IMPL_OPENCL_KERNEL_HPP
15 changes: 15 additions & 0 deletions hasty_impl/include/opencl/opencl_kernel_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef HASTY_IMPL_OPENCL_KERNEL_IMPL_H
#define HASTY_IMPL_OPENCL_KERNEL_IMPL_H
#ifdef HASTY_IMPL_HAS_OPENCL

#include "./opencl_error_types.h"
#include "./opencl_memory_impl.h"

enum OpenCLErrorCode opencl_add_kernel_ffi(const char *kernelSource);

enum OpenCLErrorCode
opencl_run_contiguous_linear_kernel_3_ffi(const char *kernelName, uint64_t numElements, void *buf0, void *buf1,
void *buf2);

#endif // HASTY_IMPL_HAS_OPENCL
#endif //HASTY_IMPL_OPENCL_KERNEL_IMPL_H
10 changes: 5 additions & 5 deletions hasty_impl/include/opencl/opencl_memory_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ enum OpenCLMemCopyType {
DeviceToHost
};

enum OpenCLErrorCode opencl_allocate_voidptr(uint64_t bytes, enum OpenCLMemoryType mem_type, void **ptr);
enum OpenCLErrorCode opencl_allocate_ffi(uint64_t bytes, enum OpenCLMemoryType mem_type, void **ptr);

void opencl_free_voidptr(void *buf);
void opencl_free_ffi(void *buf);

enum OpenCLErrorCode opencl_write_voidptr(void *dst, const void *src, uint64_t bytes);
enum OpenCLErrorCode opencl_write_ffi(void *dst, const void *src, uint64_t bytes);

enum OpenCLErrorCode opencl_read_voidptr(void *dst, const void *src, uint64_t bytes);
enum OpenCLErrorCode opencl_read_ffi(void *dst, const void *src, uint64_t bytes);

enum OpenCLErrorCode opencl_copy_voidptr(void *dst, const void *src, uint64_t bytes);
enum OpenCLErrorCode opencl_copy_ffi(void *dst, const void *src, uint64_t bytes);

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion hasty_impl/src/opencl/opencl_configure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ c[i] = a[i] + b[i];
// Check the build status
cl_build_status buildStatus = program.getBuildInfo<CL_PROGRAM_BUILD_STATUS>(device);

if (buildStatus != CL_BUILD_SUCCESS) {
if (buildStatus != CL_BUILD_SUCCESS || err != CL_SUCCESS) {
return false;
}

Expand Down
2 changes: 2 additions & 0 deletions hasty_impl/src/opencl/opencl_global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace global {
cl::Device openCLDevice;
cl::Context openCLContext;
cl::CommandQueue openCLQueue;
cl::Program::Sources openCLSources;
cl::Program openCLProgram;
}

#else
Expand Down
41 changes: 41 additions & 0 deletions hasty_impl/src/opencl/opencl_kernel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifdef HASTY_IMPL_HAS_OPENCL

#include <vector>
#include <iostream>
#include <hasty_opencl.h>
#include <opencl/opencl.hpp>
#include <opencl/opencl_errors.hpp>
#include <opencl/opencl_global.hpp>
#include <opencl/opencl_kernel.hpp>
#include <clblast.h>

OpenCLErrorCode opencl_add_kernel(const std::string &kernelSource) {
global::openCLSources.push_back({kernelSource.c_str(), kernelSource.length()});
global::openCLProgram = cl::Program(global::openCLContext, global::openCLSources);
return get_opencl_error_code(global::openCLProgram.build());
}

#ifdef __cplusplus
extern "C" {
#endif

enum OpenCLErrorCode opencl_add_kernel_ffi(const char *kernelSource) {
return opencl_add_kernel(std::string(kernelSource));
}

enum OpenCLErrorCode
opencl_run_contiguous_linear_kernel_3_ffi(const char *kernelName, uint64_t numElements, void *buf0, void *buf1,
void *buf2) {
return opencl_run_contiguous_linear_kernel(std::string(kernelName), numElements, *(cl::Buffer *) buf0,
*(cl::Buffer *) buf1, *(cl::Buffer *) buf2);
}

#ifdef __cplusplus
}
#endif

#else

void opencl_kernel_placeholder() {}

#endif // HASTY_IMPL_HAS_OPENCL
10 changes: 5 additions & 5 deletions hasty_impl/src/opencl/opencl_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,23 @@ OpenCLErrorCode opencl_copy(cl::Buffer &dst, const cl::Buffer &src, size_t bytes
extern "C" {
#endif

OpenCLErrorCode opencl_allocate_voidptr(uint64_t bytes, OpenCLMemoryType mem_type, void **ptr) {
OpenCLErrorCode opencl_allocate_ffi(uint64_t bytes, OpenCLMemoryType mem_type, void **ptr) {
return opencl_allocate(bytes, mem_type, (cl::Buffer **) (ptr));
}

void opencl_free_voidptr(void *buf) {
void opencl_free_ffi(void *buf) {
delete (cl::Buffer *) buf;
}

OpenCLErrorCode opencl_write_voidptr(void *dst, const void *src, uint64_t bytes) {
OpenCLErrorCode opencl_write_ffi(void *dst, const void *src, uint64_t bytes) {
return opencl_write(*(cl::Buffer *) dst, src, bytes);
}

OpenCLErrorCode opencl_read_voidptr(void *dst, const void *src, uint64_t bytes) {
OpenCLErrorCode opencl_read_ffi(void *dst, const void *src, uint64_t bytes) {
return opencl_read(dst, *(cl::Buffer *) src, bytes);
}

OpenCLErrorCode opencl_copy_voidptr(void *dst, const void *src, uint64_t bytes) {
OpenCLErrorCode opencl_copy_ffi(void *dst, const void *src, uint64_t bytes) {
return opencl_copy(*(cl::Buffer *) dst, *(cl::Buffer *) src, bytes);
}

Expand Down
67 changes: 46 additions & 21 deletions src/opencl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,11 @@ pub unsafe fn configure_opencl() {
pub unsafe fn opencl_allocate(bytes: usize, mem_type: OpenCLMemoryType) -> Result<*mut ::std::os::raw::c_void, OpenCLErrorCode> {
let mut buffer: *mut ::std::os::raw::c_void = ::std::ptr::null_mut();

let ret = hasty_impl::opencl_allocate_voidptr(bytes as u64, mem_type.to_ffi(), &mut buffer);
let ret = hasty_impl::opencl_allocate_ffi(bytes as u64, mem_type.to_ffi(), &mut buffer);

if ret == hasty_impl::OpenCLErrorCode_Success {
Ok(buffer)
} else {
Err(OpenCLErrorCode::from_ffi(ret))
match ret {
hasty_impl::OpenCLErrorCode_Success => Ok(buffer),
_ => Err(OpenCLErrorCode::from_ffi(ret)),
}
}

Expand All @@ -362,20 +361,19 @@ pub unsafe fn opencl_allocate(bytes: usize, mem_type: OpenCLMemoryType) -> Resul
/// could not be freed, it will panic (or segfault...). As a result, the function
/// signature is `unsafe` -- the caller must ensure that the memory can be freed.
pub unsafe fn opencl_free(buffer: *mut ::std::os::raw::c_void) {
hasty_impl::opencl_free_voidptr(buffer);
hasty_impl::opencl_free_ffi(buffer);
}

/// Write data to OpenCL device memory from host memory
///
/// **Note**: There are no checks on the pointers, nor the size of the data. The caller
/// must ensure that everything is valid.
pub unsafe fn opencl_write(dst: *mut ::std::os::raw::c_void, src: *const ::std::os::raw::c_void, bytes: usize) -> Result<(), OpenCLErrorCode> {
let ret = hasty_impl::opencl_write_voidptr(dst, src, bytes as u64);
let ret = hasty_impl::opencl_write_ffi(dst, src, bytes as u64);

if ret == hasty_impl::OpenCLErrorCode_Success {
Ok(())
} else {
Err(OpenCLErrorCode::from_ffi(ret))
match ret {
hasty_impl::OpenCLErrorCode_Success => Ok(()),
_ => Err(OpenCLErrorCode::from_ffi(ret)),
}
}

Expand All @@ -384,12 +382,11 @@ pub unsafe fn opencl_write(dst: *mut ::std::os::raw::c_void, src: *const ::std::
/// **Note**: There are no checks on the pointers, nor the size of the data. The caller
/// must ensure that everything is valid.
pub unsafe fn opencl_read(dst: *mut ::std::os::raw::c_void, src: *const ::std::os::raw::c_void, bytes: usize) -> Result<(), OpenCLErrorCode> {
let ret = hasty_impl::opencl_read_voidptr(dst, src, bytes as u64);
let ret = hasty_impl::opencl_read_ffi(dst, src, bytes as u64);

if ret == hasty_impl::OpenCLErrorCode_Success {
Ok(())
} else {
Err(OpenCLErrorCode::from_ffi(ret))
match ret {
hasty_impl::OpenCLErrorCode_Success => Ok(()),
_ => Err(OpenCLErrorCode::from_ffi(ret)),
}
}

Expand All @@ -398,12 +395,40 @@ pub unsafe fn opencl_read(dst: *mut ::std::os::raw::c_void, src: *const ::std::o
/// **Note**: There are no checks on the pointers, nor the size of the data. The caller
/// must ensure that everything is valid.
pub unsafe fn opencl_copy(dst: *mut ::std::os::raw::c_void, src: *const ::std::os::raw::c_void, bytes: usize) -> Result<(), OpenCLErrorCode> {
let ret = hasty_impl::opencl_copy_voidptr(dst, src, bytes as u64);
let ret = hasty_impl::opencl_copy_ffi(dst, src, bytes as u64);

if ret == hasty_impl::OpenCLErrorCode_Success {
Ok(())
} else {
Err(OpenCLErrorCode::from_ffi(ret))
match ret {
hasty_impl::OpenCLErrorCode_Success => Ok(()),
_ => Err(OpenCLErrorCode::from_ffi(ret)),
}
}

pub unsafe fn opencl_add_kernel(src: &str) -> Result<(), OpenCLErrorCode> {
let ret = hasty_impl::opencl_add_kernel_ffi(std::ffi::CString::new(src).expect("Failed to convert source code to CString").as_ptr());

match ret {
hasty_impl::OpenCLErrorCode_Success => Ok(()),
_ => Err(OpenCLErrorCode::from_ffi(ret)),
}
}

pub unsafe fn opencl_run_contiguous_linear_kernel_3(
kernel_name: &str,
num_elements: usize,
buf_0: *mut ::std::os::raw::c_void,
buf_1: *mut ::std::os::raw::c_void,
buf_2: *mut ::std::os::raw::c_void,
) -> Result<(), OpenCLErrorCode> {
let ret = hasty_impl::opencl_run_contiguous_linear_kernel_3_ffi(
std::ffi::CString::new(kernel_name).expect("Failed to convert kernel name to CString").as_ptr(),
num_elements as u64,
buf_0,
buf_1,
buf_2,
);

match ret {
hasty_impl::OpenCLErrorCode_Success => Ok(()),
_ => Err(OpenCLErrorCode::from_ffi(ret)),
}
}

0 comments on commit 918da5b

Please sign in to comment.