Skip to content

Program scope hostpipe support #284

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

Merged
merged 2 commits into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions include/CL/cl_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -2384,6 +2384,64 @@ clCreateBufferWithPropertiesINTEL_fn)(
void * host_ptr,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;

/***********************************
* cl_intel_program_scope_host_pipe *
***********************************/
#define cl_intel_program_scope_host_pipe 1
#define CL_INTEL_PROGRAM_SCOPE_HOST_PIPE_EXTENSION_NAME "cl_intel_program_scope_host_pipe"

/* New return values from clGetEventInfo when param_name is CL_EVENT_COMMAND_TYPE */
#define CL_COMMAND_READ_HOST_PIPE_INTEL 0x4214
#define CL_COMMAND_WRITE_HOST_PIPE_INTEL 0x4215
#define CL_PROGRAM_NUM_HOST_PIPES_INTEL 0x4216
#define CL_PROGRAM_HOST_PIPE_NAMES_INTEL 0x4217

typedef cl_int (CL_API_CALL *clEnqueueReadHostPipeINTEL_fn )(
cl_command_queue command_queue,
cl_program program,
const char* pipe_symbol,
cl_bool blocking_read,
void* ptr,
size_t size,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_API_SUFFIX__VERSION_1_0;

extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueReadHostPipeINTEL(
cl_command_queue command_queue,
cl_program program,
const char* pipe_symbol,
cl_bool blocking_read,
void* ptr,
size_t size,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_API_SUFFIX__VERSION_1_0;

typedef cl_int (CL_API_CALL *clEnqueueWriteHostPipeINTEL_fn)(
cl_command_queue command_queue,
cl_program program,
const char* pipe_symbol,
cl_bool blocking_write,
const void* ptr,
size_t size,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_API_SUFFIX__VERSION_1_0;

extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueWriteHostPipeINTEL(
cl_command_queue command_queue,
cl_program program,
const char* pipe_symbol,
cl_bool blocking_write,
const void* ptr,
size_t size,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_API_SUFFIX__VERSION_1_0;

/******************************************
* cl_intel_mem_channel_property extension *
*******************************************/
Expand Down
15 changes: 15 additions & 0 deletions include/acl.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,19 @@ struct acl_device_global_mem_def_t {
bool reset_on_reuse;
};

// Mapping of logical to physical host pipes.
struct acl_hostpipe_mapping {
std::string logical_name;
std::string physical_name; // chan_id in the board_spec.xml
bool implement_in_csr;
std::string csr_address; // Store this as string as this value can be '-' for
// non-CSR pipe.
bool is_read;
bool is_write;
unsigned pipe_width;
unsigned pipe_depth;
};

// Part of acl_device_def_t where members are populated from the information
// in the autodiscovery string. This will get updated every time the device
// is programmed with a new device binary as the new binary would contain a
Expand All @@ -548,6 +561,8 @@ typedef struct acl_device_def_autodiscovery_t {
device_global_mem_defs;
bool cra_ring_root_exist =
true; // Set the default value to true for backwards compatibility flows.

std::vector<acl_hostpipe_mapping> hostpipe_mappings;
} acl_device_def_autodiscovery_t;

typedef struct acl_device_def_t {
Expand Down
8 changes: 7 additions & 1 deletion include/acl_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ typedef struct {
size_t read_size, int *status);
/// Push write_size of data to the device from host_buffer
size_t (*hostchannel_push)(unsigned int physical_device_id,
int channel_handle, void *host_buffer,
int channel_handle, const void *host_buffer,
size_t write_size, int *status);
/// Get a pointer to the mmd buffer for the host channel
void *(*hostchannel_get_buffer)(unsigned int physical_device_id,
Expand Down Expand Up @@ -246,6 +246,12 @@ typedef struct {
void (*simulation_streaming_kernel_done)(unsigned int physical_device_id,
const std::string &signal_name,
unsigned int &finish_counter);

size_t (*read_csr)(unsigned int physical_device_id, uintptr_t offset,
void *ptr, size_t size);

size_t (*write_csr)(unsigned int physical_device_id, uintptr_t offset,
const void *ptr, size_t size);
} acl_hal_t;

/// Linked list of MMD library names to load.
Expand Down
13 changes: 13 additions & 0 deletions include/acl_hostch.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ void acl_bind_and_process_all_pipes_transactions(
cl_context context, cl_device_id device,
const acl_device_def_autodiscovery_t &devdef);

// Submit a program hostpipe read device operation to the device op queue
// acl_read_program_hostpipe will be invoked when the read op is RUNNING
cl_int acl_submit_read_program_hostpipe_device_op(cl_event event);
// Submit a program hostpipe write device operation to the device op queue
cl_int acl_submit_write_program_hostpipe_device_op(cl_event event);

// Read from a program hostpipe
void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op);

// Write into a program hostpipe
// acl_write_program_hostpipe will be invoked when the write op is RUNNING
void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op);

#define HOST_TO_DEVICE 1
#define DEVICE_TO_HOST 0

Expand Down
114 changes: 74 additions & 40 deletions include/acl_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,54 @@ typedef void(CL_CALLBACK *acl_event_notify_fn_t)(
typedef void(CL_CALLBACK *acl_mem_destructor_notify_fn_t)(cl_mem memobj,
void *user_data);

enum host_op_type { MAP, PACKET };

typedef struct host_op_struct {
enum host_op_type m_op;
void *m_mmd_buffer;
void *m_host_buffer;
size_t m_op_size;
size_t m_size_sent;
} host_op_t;

typedef struct host_pipe_struct {
// The handle to the device needed for mmd call
unsigned int m_physical_device_id;

// The channel handle returned by mmd create hostch call
int m_channel_handle;

// Operations on the host pipe are queued here. map/packet ops
std::deque<host_op_t> m_host_op_queue;
// host_op_t * m_host_op_queue;

// The total size of the operations we're queuing on the pinned mmd buffer
size_t size_buffered;

// The kernel that the host pipe is binded to
cl_kernel m_binded_kernel;

// Is host pipe binded to kernel device, only done at kernel enqueue time
bool binded;

// Channel ID name that the host pipe will use to do the binding
std::string host_pipe_channel_id;

// Pipe specific lock. Obtained every time we do an operation on the pipe
acl_mutex_t m_lock;

// The following are the new entries introduced by the program scoped
// hostpipes

// Whether this program hostpipe is implemented in the CSR
bool implement_in_csr;

// The CSR address of this hostpipe. Compiler passes a csr_address = '-' for
// non-CSR program hostpipe
std::string csr_address;

} host_pipe_t;

// The device-specific information about a program.
//
// This object is owned by the cl_program that creates it during
Expand Down Expand Up @@ -350,6 +398,9 @@ class acl_device_program_info_t {
// Return all the names of the kernels in this device program.
std::set<std::string> get_all_kernel_names() const;

// Map logical hostpipe name to the hostpipe struct
std::unordered_map<std::string, host_pipe_t> program_hostpipe_map;

private:
// This map is only used when split_kernel == 1 in the enclosing
// cl_context. This maps a hashed kernel name to the acl_device_binary_t that
Expand Down Expand Up @@ -551,6 +602,17 @@ typedef struct {

} ndrange_kernel;

struct {
// Used for program scoped hostpipe
size_t size;
void *ptr;
const void *write_ptr;
bool blocking;
const char *logical_name; // Use char* instead string here due to a
// compilation error from acl_command_info_t
// constructor malloc related
} host_pipe_info;

// Reprogram the device, without an associated kernel enqueue.
// This is used to hide the latency of device programming on host
// program startup.
Expand Down Expand Up @@ -684,43 +746,6 @@ typedef struct acl_mem_destructor_user_callback {
mem_destructor_notify_fn; // The callback function, provided by the user.
} acl_mem_destructor_user_callback;

enum host_op_type { MAP, PACKET };

typedef struct host_op_struct {
enum host_op_type m_op;
void *m_mmd_buffer;
void *m_host_buffer;
size_t m_op_size;
size_t m_size_sent;
} host_op_t;

typedef struct host_pipe_struct {
// The handle to the device needed for mmd call
unsigned int m_physical_device_id;

// The channel handle returned by mmd create hostch call
int m_channel_handle;

// Operations on the host pipe are queued here. map/packet ops
std::deque<host_op_t> m_host_op_queue;
// host_op_t * m_host_op_queue;

// The total size of the operations we're queuing on the pinned mmd buffer
size_t size_buffered;

// The kernel that the host pipe is binded to
cl_kernel m_binded_kernel;

// Is host pipe binded to kernel device, only done at kernel enqueue time
bool binded;

// Channel ID name that the host pipe will use to do the binding
std::string host_pipe_channel_id;

// Pipe specific lock. Obtained every time we do an operation on the pipe
acl_mutex_t m_lock;
} host_pipe_t;

// The bookkeeping required to keep track of a block of allocated memory.
// The storage for these structs is owned by the acl_platform object.
// But these structs are only valid when attached to a valid context.
Expand Down Expand Up @@ -1298,10 +1323,12 @@ typedef enum {
// USM Memcpy that should call HAL's copy API without any extra work.
// Corresponds to acl_command_info_t.info.ptr_xfer
,
ACL_DEVICE_OP_USM_MEMCPY

,
ACL_DEVICE_OP_USM_MEMCPY,
// Progrgam based hostpipe read or write
ACL_DEVICE_OP_HOSTPIPE_READ,
ACL_DEVICE_OP_HOSTPIPE_WRITE,
ACL_NUM_DEVICE_OP_TYPES

} acl_device_op_type_t;

// These are device operation conflict types.
Expand All @@ -1327,6 +1354,11 @@ typedef enum {
,
ACL_CONFLICT_REPROGRAM // Acts like a device reprogram
,
ACL_CONFLICT_HOSTPIPE_READ // Acts like a hostpipe read from the host channel
,
ACL_CONFLICT_HOSTPIPE_WRITE // Acts like a hostpipe write from the host
// channel
,
ACL_NUM_CONFLICT_TYPES
} acl_device_op_conflict_type_t;

Expand Down Expand Up @@ -1541,6 +1573,8 @@ typedef struct acl_device_op_queue_t {
void (*usm_memcpy)(void *, acl_device_op_t *);
// For test purposes, log transition to CL_RUNNING, CL_COMPLETE
void (*log_update)(void *, acl_device_op_t *, int new_status);
void (*hostpipe_read)(void *, acl_device_op_t *);
void (*hostpipe_write)(void *, acl_device_op_t *);
void *user_data; // The first argument provided to the callbacks.

} acl_device_op_queue_t;
Expand Down
Loading