Skip to content

Commit 704f98a

Browse files
committed
Support program scope hostpipe
1. Support program scope hostpipe, CSR pipe and non-CSR pipe. 2. Register program scoped hostpipes during program creation. 3. Create new command op and device op for the hostpipe read and write. 4. Create unit tests for the new autodiscovery string entry 5. Fix Klocwork issues in the deivce op unit test as they are flagged as new failures (they are not) due to my change in the device op
1 parent 1c20717 commit 704f98a

17 files changed

+864
-132
lines changed

include/CL/cl_ext.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,64 @@ clCreateBufferWithPropertiesINTEL_fn)(
23842384
void * host_ptr,
23852385
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
23862386

2387+
/***********************************
2388+
* cl_intel_program_scope_host_pipe *
2389+
***********************************/
2390+
#define cl_intel_program_scope_host_pipe 1
2391+
#define CL_INTEL_PROGRAM_SCOPE_HOST_PIPE_EXTENSION_NAME "cl_intel_program_scope_host_pipe"
2392+
2393+
/* New return values from clGetEventInfo when param_name is CL_EVENT_COMMAND_TYPE */
2394+
#define CL_COMMAND_READ_HOST_PIPE_INTEL 0x4214
2395+
#define CL_COMMAND_WRITE_HOST_PIPE_INTEL 0x4215
2396+
#define CL_PROGRAM_NUM_HOST_PIPES_INTEL 0x4216
2397+
#define CL_PROGRAM_HOST_PIPE_NAMES_INTEL 0x4217
2398+
2399+
typedef cl_int (CL_API_CALL *clEnqueueReadHostPipeINTEL_fn )(
2400+
cl_command_queue command_queue,
2401+
cl_program program,
2402+
const char* pipe_symbol,
2403+
cl_bool blocking_read,
2404+
void* ptr,
2405+
size_t size,
2406+
cl_uint num_events_in_wait_list,
2407+
const cl_event* event_wait_list,
2408+
cl_event* event) CL_API_SUFFIX__VERSION_1_0;
2409+
2410+
extern CL_API_ENTRY cl_int CL_API_CALL
2411+
clEnqueueReadHostPipeINTEL(
2412+
cl_command_queue command_queue,
2413+
cl_program program,
2414+
const char* pipe_symbol,
2415+
cl_bool blocking_read,
2416+
void* ptr,
2417+
size_t size,
2418+
cl_uint num_events_in_wait_list,
2419+
const cl_event* event_wait_list,
2420+
cl_event* event) CL_API_SUFFIX__VERSION_1_0;
2421+
2422+
typedef cl_int (CL_API_CALL *clEnqueueWriteHostPipeINTEL_fn)(
2423+
cl_command_queue command_queue,
2424+
cl_program program,
2425+
const char* pipe_symbol,
2426+
cl_bool blocking_write,
2427+
const void* ptr,
2428+
size_t size,
2429+
cl_uint num_events_in_wait_list,
2430+
const cl_event* event_wait_list,
2431+
cl_event* event) CL_API_SUFFIX__VERSION_1_0;
2432+
2433+
extern CL_API_ENTRY cl_int CL_API_CALL
2434+
clEnqueueWriteHostPipeINTEL(
2435+
cl_command_queue command_queue,
2436+
cl_program program,
2437+
const char* pipe_symbol,
2438+
cl_bool blocking_write,
2439+
const void* ptr,
2440+
size_t size,
2441+
cl_uint num_events_in_wait_list,
2442+
const cl_event* event_wait_list,
2443+
cl_event* event) CL_API_SUFFIX__VERSION_1_0;
2444+
23872445
/******************************************
23882446
* cl_intel_mem_channel_property extension *
23892447
*******************************************/

include/acl.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,9 +527,14 @@ struct acl_device_global_mem_def_t {
527527
// Mapping of logical to physical host pipes.
528528
struct acl_hostpipe_mapping {
529529
std::string logical_name;
530-
std::string physical_name;
530+
std::string physical_name; // chan_id in the board_spec.xml
531531
bool implement_in_csr;
532-
uintptr_t csr_address;
532+
std::string csr_address; // Store this as string as this value can be '-' for
533+
// non-CSR pipe.
534+
bool is_read;
535+
bool is_write;
536+
unsigned pipe_width;
537+
unsigned pipe_depth;
533538
};
534539

535540
// Part of acl_device_def_t where members are populated from the information

include/acl_hal.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ typedef struct {
205205
size_t read_size, int *status);
206206
/// Push write_size of data to the device from host_buffer
207207
size_t (*hostchannel_push)(unsigned int physical_device_id,
208-
int channel_handle, void *host_buffer,
208+
int channel_handle, const void *host_buffer,
209209
size_t write_size, int *status);
210210
/// Get a pointer to the mmd buffer for the host channel
211211
void *(*hostchannel_get_buffer)(unsigned int physical_device_id,
@@ -246,6 +246,12 @@ typedef struct {
246246
void (*simulation_streaming_kernel_done)(unsigned int physical_device_id,
247247
const std::string &signal_name,
248248
unsigned int &finish_counter);
249+
250+
size_t (*read_csr)(unsigned int physical_device_id, uintptr_t offset,
251+
void *ptr, size_t size);
252+
253+
size_t (*write_csr)(unsigned int physical_device_id, uintptr_t offset,
254+
const void *ptr, size_t size);
249255
} acl_hal_t;
250256

251257
/// Linked list of MMD library names to load.

include/acl_hostch.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ void acl_bind_and_process_all_pipes_transactions(
2727
cl_context context, cl_device_id device,
2828
const acl_device_def_autodiscovery_t &devdef);
2929

30+
// Submit a program hostpipe read device operation to the device op queue
31+
// acl_read_program_hostpipe will be invoked when the read op is RUNNING
32+
cl_int acl_submit_read_program_hostpipe_device_op(cl_event event);
33+
// Submit a program hostpipe write device operation to the device op queue
34+
cl_int acl_submit_write_program_hostpipe_device_op(cl_event event);
35+
36+
// Read from a program hostpipe
37+
void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op);
38+
39+
// Write into a program hostpipe
40+
// acl_write_program_hostpipe will be invoked when the write op is RUNNING
41+
void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op);
42+
3043
#define HOST_TO_DEVICE 1
3144
#define DEVICE_TO_HOST 0
3245

include/acl_types.h

Lines changed: 74 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,54 @@ typedef void(CL_CALLBACK *acl_event_notify_fn_t)(
285285
typedef void(CL_CALLBACK *acl_mem_destructor_notify_fn_t)(cl_mem memobj,
286286
void *user_data);
287287

288+
enum host_op_type { MAP, PACKET };
289+
290+
typedef struct host_op_struct {
291+
enum host_op_type m_op;
292+
void *m_mmd_buffer;
293+
void *m_host_buffer;
294+
size_t m_op_size;
295+
size_t m_size_sent;
296+
} host_op_t;
297+
298+
typedef struct host_pipe_struct {
299+
// The handle to the device needed for mmd call
300+
unsigned int m_physical_device_id;
301+
302+
// The channel handle returned by mmd create hostch call
303+
int m_channel_handle;
304+
305+
// Operations on the host pipe are queued here. map/packet ops
306+
std::deque<host_op_t> m_host_op_queue;
307+
// host_op_t * m_host_op_queue;
308+
309+
// The total size of the operations we're queuing on the pinned mmd buffer
310+
size_t size_buffered;
311+
312+
// The kernel that the host pipe is binded to
313+
cl_kernel m_binded_kernel;
314+
315+
// Is host pipe binded to kernel device, only done at kernel enqueue time
316+
bool binded;
317+
318+
// Channel ID name that the host pipe will use to do the binding
319+
std::string host_pipe_channel_id;
320+
321+
// Pipe specific lock. Obtained every time we do an operation on the pipe
322+
acl_mutex_t m_lock;
323+
324+
// The following are the new entries introduced by the program scoped
325+
// hostpipes
326+
327+
// Whether this program hostpipe is implemented in the CSR
328+
bool implement_in_csr;
329+
330+
// The CSR address of this hostpipe. Compiler passes a csr_address = '-' for
331+
// non-CSR program hostpipe
332+
std::string csr_address;
333+
334+
} host_pipe_t;
335+
288336
// The device-specific information about a program.
289337
//
290338
// This object is owned by the cl_program that creates it during
@@ -350,6 +398,9 @@ class acl_device_program_info_t {
350398
// Return all the names of the kernels in this device program.
351399
std::set<std::string> get_all_kernel_names() const;
352400

401+
// Map logical hostpipe name to the hostpipe struct
402+
std::unordered_map<std::string, host_pipe_t> program_hostpipe_map;
403+
353404
private:
354405
// This map is only used when split_kernel == 1 in the enclosing
355406
// cl_context. This maps a hashed kernel name to the acl_device_binary_t that
@@ -551,6 +602,17 @@ typedef struct {
551602

552603
} ndrange_kernel;
553604

605+
struct {
606+
// Used for program scoped hostpipe
607+
size_t size;
608+
void *ptr;
609+
const void *write_ptr;
610+
bool blocking;
611+
const char *logical_name; // Use char* instead string here due to a
612+
// compilation error from acl_command_info_t
613+
// constructor malloc related
614+
} host_pipe_info;
615+
554616
// Reprogram the device, without an associated kernel enqueue.
555617
// This is used to hide the latency of device programming on host
556618
// program startup.
@@ -684,43 +746,6 @@ typedef struct acl_mem_destructor_user_callback {
684746
mem_destructor_notify_fn; // The callback function, provided by the user.
685747
} acl_mem_destructor_user_callback;
686748

687-
enum host_op_type { MAP, PACKET };
688-
689-
typedef struct host_op_struct {
690-
enum host_op_type m_op;
691-
void *m_mmd_buffer;
692-
void *m_host_buffer;
693-
size_t m_op_size;
694-
size_t m_size_sent;
695-
} host_op_t;
696-
697-
typedef struct host_pipe_struct {
698-
// The handle to the device needed for mmd call
699-
unsigned int m_physical_device_id;
700-
701-
// The channel handle returned by mmd create hostch call
702-
int m_channel_handle;
703-
704-
// Operations on the host pipe are queued here. map/packet ops
705-
std::deque<host_op_t> m_host_op_queue;
706-
// host_op_t * m_host_op_queue;
707-
708-
// The total size of the operations we're queuing on the pinned mmd buffer
709-
size_t size_buffered;
710-
711-
// The kernel that the host pipe is binded to
712-
cl_kernel m_binded_kernel;
713-
714-
// Is host pipe binded to kernel device, only done at kernel enqueue time
715-
bool binded;
716-
717-
// Channel ID name that the host pipe will use to do the binding
718-
std::string host_pipe_channel_id;
719-
720-
// Pipe specific lock. Obtained every time we do an operation on the pipe
721-
acl_mutex_t m_lock;
722-
} host_pipe_t;
723-
724749
// The bookkeeping required to keep track of a block of allocated memory.
725750
// The storage for these structs is owned by the acl_platform object.
726751
// But these structs are only valid when attached to a valid context.
@@ -1298,10 +1323,12 @@ typedef enum {
12981323
// USM Memcpy that should call HAL's copy API without any extra work.
12991324
// Corresponds to acl_command_info_t.info.ptr_xfer
13001325
,
1301-
ACL_DEVICE_OP_USM_MEMCPY
1302-
1303-
,
1326+
ACL_DEVICE_OP_USM_MEMCPY,
1327+
// Progrgam based hostpipe read or write
1328+
ACL_DEVICE_OP_HOSTPIPE_READ,
1329+
ACL_DEVICE_OP_HOSTPIPE_WRITE,
13041330
ACL_NUM_DEVICE_OP_TYPES
1331+
13051332
} acl_device_op_type_t;
13061333

13071334
// These are device operation conflict types.
@@ -1327,6 +1354,11 @@ typedef enum {
13271354
,
13281355
ACL_CONFLICT_REPROGRAM // Acts like a device reprogram
13291356
,
1357+
ACL_CONFLICT_HOSTPIPE_READ // Acts like a hostpipe read from the host channel
1358+
,
1359+
ACL_CONFLICT_HOSTPIPE_WRITE // Acts like a hostpipe write from the host
1360+
// channel
1361+
,
13301362
ACL_NUM_CONFLICT_TYPES
13311363
} acl_device_op_conflict_type_t;
13321364

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

15461580
} acl_device_op_queue_t;

src/acl_auto_configure.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ static bool read_uintptr_counters(const std::string &str,
221221
}
222222

223223
val = static_cast<uintptr_t>(parsed);
224+
// To make sure the cast work
225+
// As `unsigned long long` might have difference size comparing to `uintptr_t
224226
if (val != parsed) {
225227
return false;
226228
}
@@ -644,14 +646,21 @@ static bool read_hostpipe_mappings(
644646
counters.emplace_back(num_fields_per_mapping);
645647

646648
acl_hostpipe_mapping mapping{};
647-
result = read_string_counters(config_str, curr_pos, mapping.logical_name,
648-
counters) &&
649-
read_string_counters(config_str, curr_pos, mapping.physical_name,
650-
counters) &&
651-
read_bool_counters(config_str, curr_pos, mapping.implement_in_csr,
652-
counters) &&
653-
read_uintptr_counters(config_str, curr_pos, mapping.csr_address,
654-
counters);
649+
result =
650+
read_string_counters(config_str, curr_pos, mapping.logical_name,
651+
counters) &&
652+
read_string_counters(config_str, curr_pos, mapping.physical_name,
653+
counters) &&
654+
read_bool_counters(config_str, curr_pos, mapping.implement_in_csr,
655+
counters) &&
656+
read_string_counters(config_str, curr_pos, mapping.csr_address,
657+
counters) &&
658+
read_bool_counters(config_str, curr_pos, mapping.is_read, counters) &&
659+
read_bool_counters(config_str, curr_pos, mapping.is_write, counters) &&
660+
read_uint_counters(config_str, curr_pos, mapping.pipe_width,
661+
counters) &&
662+
read_uint_counters(config_str, curr_pos, mapping.pipe_depth, counters);
663+
655664
hostpipe_mappings.emplace_back(mapping);
656665

657666
while (result && counters.back() > 0) {
@@ -839,7 +848,6 @@ static bool read_accel_defs(const std::string &config_str,
839848
accel = std::vector<acl_accel_def_t>(num_accel);
840849
hal_info = std::vector<acl_hal_accel_def_t>(num_accel);
841850
}
842-
843851
// Setup the accelerators
844852
for (auto i = 0U; result && (i < num_accel); i++) {
845853
accel[i].id = i;
@@ -931,6 +939,7 @@ static bool read_accel_defs(const std::string &config_str,
931939
result = read_int_counters(config_str, curr_pos, total_fields_printf,
932940
counters);
933941
}
942+
934943
for (auto j = 0U; result && (j < accel[i].printf_format_info.size()); j++) {
935944
counters.emplace_back(total_fields_printf);
936945
result =
@@ -1197,6 +1206,7 @@ bool acl_load_device_def_from_str(const std::string &config_str,
11971206
if (result && counters.back() > 0) {
11981207
result = read_bool_counters(config_str, curr_pos,
11991208
devdef.cra_ring_root_exist, counters);
1209+
}
12001210

12011211
// Read program scoped hostpipes mappings
12021212
if (result && counters.back() > 0) {

src/acl_command.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <acl_event.h>
1717
#include <acl_globals.h>
1818
#include <acl_hal.h>
19+
#include <acl_hostch.h>
1920
#include <acl_kernel.h>
2021
#include <acl_mem.h>
2122
#include <acl_program.h>
@@ -371,6 +372,14 @@ int acl_submit_command(cl_event event) {
371372
result = acl_submit_migrate_mem_device_op(event);
372373
break;
373374

375+
case CL_COMMAND_READ_HOST_PIPE_INTEL:
376+
result = acl_submit_read_program_hostpipe_device_op(event);
377+
break;
378+
379+
case CL_COMMAND_WRITE_HOST_PIPE_INTEL:
380+
result = acl_submit_write_program_hostpipe_device_op(event);
381+
break;
382+
374383
default:
375384
acl_print_debug_msg(" acl_submit_command: unknown cmd type %d\n",
376385
event->cmd.type);

0 commit comments

Comments
 (0)