diff --git a/include/acl_globals.h b/include/acl_globals.h index bcc7e8ba..dfb3a1dc 100644 --- a/include/acl_globals.h +++ b/include/acl_globals.h @@ -44,18 +44,8 @@ void acl_reset(void); // if it is not. cl_bool acl_init_from_hal_discovery(void); -// Looks at environment variable CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA. -// If it exists and is prefixed by "+" then: -// Return a pointer to the device name (without the "+" prefix). -// Set *use_offline_ret_only = 1 -// If it exists and is not prefixed by "+" then -// Return a pointer to the device name. -// Set *use_offline_ret_only = 0 -#define ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY 0 -#define ACL_CONTEXT_OFFLINE_ONLY 1 -#define ACL_CONTEXT_MSIM 3 -#define ACL_CONTEXT_MPSIM 4 -const char *acl_get_offline_device_user_setting(int *use_offline_only_ret); +acl_context_offline_mode_t +acl_get_offline_device_user_setting(std::string *offline_device); ACL_EXPORT extern struct _cl_platform_id acl_platform; diff --git a/include/acl_types.h b/include/acl_types.h index 60d1c2e7..78671d7b 100644 --- a/include/acl_types.h +++ b/include/acl_types.h @@ -216,6 +216,20 @@ typedef enum { ACL_COMPILER_MODE_NUM_MODES = CL_CONTEXT_COMPILER_MODE_NUM_MODES_INTELFPGA } acl_compiler_mode_t; +// Looks at environment variable CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA. +// If it exists and is prefixed by "+" then: +// Return a pointer to the device name (without the "+" prefix). +// Set *use_offline_ret_only = 1 +// If it exists and is not prefixed by "+" then +// Return a pointer to the device name. +// Set *use_offline_ret_only = 0 +typedef enum { + ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY, + ACL_CONTEXT_OFFLINE_ONLY, + ACL_CONTEXT_MSIM, + ACL_CONTEXT_MPSIM +} acl_context_offline_mode_t; + /* When a feature is still in development, it might need enum values * that are distinct from all published enums in the OpenCL token registry. * There is a reserved range for values for such "experimental" features. @@ -1226,7 +1240,8 @@ typedef struct _cl_device_id { unsigned int address_bits; // cache address bits to avoid GetDeviceInfo calls - int present; // Is the device present in the host system? + bool present; // Is the device present in the host system? + bool offline; // Is the device a real (i.e., not simulator) offline device? // Error notification callback. CL_EXCEPTION_TYPE_INTEL device_exception_status; @@ -1573,13 +1588,16 @@ typedef struct _cl_platform_id int device_exception_platform_counter; // indicates number of devices with at // least one exception - // The setting of environment variable CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA, if - // any. - std::string offline_device; + // Record whether the platform has (non-simulator) offline device, + // value will be: + // 1: if there is a valid offline device specified by environment variable + // 0: if there is no offline device specified by environment variable + // -1: if the offline device specified by environment variable is invalid + int has_offline_device; // Cache context offline mode specified by environment variables // CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA, CL_CONTEXT_MPSIM_DEVICE_INTELFPGA // or CL_CONTEXT_MSIM_DEVICE_INTELFPGA - int offline_mode; + acl_context_offline_mode_t offline_mode; // Should we track and automatically release leaked objects? // This helps immensely with the OpenCL conformance tests which tend to diff --git a/src/acl_context.cpp b/src/acl_context.cpp index cc3d6067..409f62d9 100644 --- a/src/acl_context.cpp +++ b/src/acl_context.cpp @@ -48,7 +48,6 @@ static void l_init_kernel_invocation_wrapper(acl_kernel_invocation_wrapper_t *wrapper, unsigned i); static void l_forcibly_release_allocations(cl_context context); -static cl_device_id l_find_device_by_name(const std::string &name); static cl_int l_update_program_library_root(cl_context context, const char *new_root); static cl_int l_update_compile_command(cl_context context, const char *new_cmd); @@ -606,12 +605,11 @@ static cl_int l_load_properties(cl_context context, } } - // Environment variable can specify we always an offline device. - if (!acl_platform.offline_device.empty()) { - if (!l_find_device_by_name(acl_platform.offline_device)) - ERR_RET(CL_INVALID_VALUE, context, - "Invalid offline device specified by environment variable " - "CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA"); + // Check if environment variable specified offline device is valid + if (acl_platform.has_offline_device < 0) { + ERR_RET(CL_INVALID_VALUE, context, + "Invalid offline device specified by environment variable " + "CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA"); } // Get default for program_library_root. @@ -817,17 +815,6 @@ static cl_int l_load_properties(cl_context context, return CL_SUCCESS; } -static cl_device_id l_find_device_by_name(const std::string &name) { - acl_assert_locked(); - - for (unsigned i = 0; i < acl_platform.num_devices; ++i) { - if (name == acl_platform.device[i].def.autodiscovery_def.name) { - return &(acl_platform.device[i]); - } - } - return 0; -} - // Initialize the given context. // Yes, this is like a "placement new". // @@ -883,8 +870,6 @@ static cl_int l_init_context_with_devices(cl_context context, int num_present = 0; int num_absent = 0; for (cl_uint i = 0; i < num_devices; i++) { - int usable = devices[i]->present; - // Can't mix both (actually) present and absent devices because there // is no consistent way to place device global memory. if (devices[i]->present) { @@ -900,10 +885,7 @@ static cl_int l_init_context_with_devices(cl_context context, "Can't create a context with both offline and online devices"); } - usable = usable || acl_platform.offline_device == - devices[i]->def.autodiscovery_def.name; - - if (!usable) + if (!devices[i]->present && !devices[i]->offline) ERR_RET(CL_DEVICE_NOT_AVAILABLE, context, "Device not available"); // Mark the device(s) as opened diff --git a/src/acl_globals.cpp b/src/acl_globals.cpp index 01a13121..e98494c3 100644 --- a/src/acl_globals.cpp +++ b/src/acl_globals.cpp @@ -73,8 +73,10 @@ static void l_reset_present_board() { // If it's prefixed by "+", then it's in addition to any auto-discovered // devices. // If not, then we don't even probe for auto-discovered devices. -const char *acl_get_offline_device_user_setting(int *use_offline_only_ret) { - int use_offline_only = 0; +acl_context_offline_mode_t +acl_get_offline_device_user_setting(std::string *offline_device) { + acl_context_offline_mode_t use_offline_only = + ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY; const char *setting = 0; const char *setting_deprecated = 0; const char *result = 0; @@ -136,8 +138,15 @@ const char *acl_get_offline_device_user_setting(int *use_offline_only_ret) { } } - *use_offline_only_ret = use_offline_only; - return result; + if (offline_device) { + if (use_offline_only == ACL_CONTEXT_MPSIM) { + *offline_device = ACL_MPSIM_DEVICE_NAME; + } else if (result) { + *offline_device = result; + } + } + + return use_offline_only; } int acl_init(const acl_system_def_t *newsys) { @@ -166,11 +175,11 @@ int acl_init(const acl_system_def_t *newsys) { // This function returns CL_TRUE if a hal is initialized and CL_FALSE // if it is not. cl_bool acl_init_from_hal_discovery(void) { - int use_offline_only = 0; const acl_hal_t *board_hal; acl_assert_locked(); - (void)acl_get_offline_device_user_setting(&use_offline_only); + acl_context_offline_mode_t use_offline_only = + acl_get_offline_device_user_setting(NULL); // Two jobs: // 1. Set the HAL from the linked-in HAL library. @@ -223,8 +232,8 @@ void acl_reset(void) { l_reset_present_board(); - acl_platform.offline_device = ""; acl_platform.offline_mode = ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY; + acl_platform.has_offline_device = 0; acl_platform.num_devices = 0; for (unsigned i = 0; i < ACL_MAX_DEVICE; ++i) { acl_platform.device[i] = _cl_device_id(); diff --git a/src/acl_hal_mmd.cpp b/src/acl_hal_mmd.cpp index b9e55a2f..c03d98dc 100644 --- a/src/acl_hal_mmd.cpp +++ b/src/acl_hal_mmd.cpp @@ -1199,7 +1199,6 @@ acl_mmd_get_system_definition(acl_system_def_t *sys, buf[MAX_BOARD_NAMES_LEN]; // This is a bit subtle, pointers to device // names might get cached by various routines char *ptr, *saveptr; - int use_offline_only; #ifdef _WIN32 // We're really relying on this being called before anything else @@ -1248,7 +1247,8 @@ acl_mmd_get_system_definition(acl_system_def_t *sys, #endif // Dynamically load board mmd & symbols - (void)acl_get_offline_device_user_setting(&use_offline_only); + acl_context_offline_mode_t use_offline_only = + acl_get_offline_device_user_setting(NULL); if (use_offline_only == ACL_CONTEXT_MPSIM) { // Substitute the simulator MMD layer. diff --git a/src/acl_platform.cpp b/src/acl_platform.cpp index 46986cec..6f0be526 100644 --- a/src/acl_platform.cpp +++ b/src/acl_platform.cpp @@ -54,8 +54,7 @@ struct _cl_platform_id acl_platform = { , 0 // default value for device_exception_platform_counter , - "" // No offline device specified by an environment variable, as far as we - // know right now. + 0 // No offline device specified by an environment variable so far }; // Used to detect if user is creating contexts/getting platform ids in multiple @@ -74,9 +73,9 @@ static std::vector> shipped_board_defs; ////////////////////////////// // Local functions. -static void l_initialize_offline_devices(int offline_mode); +static void l_initialize_offline_devices(std::string offline_device); static void l_initialize_devices(const acl_system_def_t *present_board_def, - int offline_mode, unsigned int num_devices, + unsigned int num_devices, const cl_device_id *devices); static void l_add_device(int idx); @@ -128,7 +127,7 @@ clGetPlatformIDsIntelFPGA(cl_uint num_entries, cl_platform_id *platforms, // - Probed devices we find actually attached to the host (probed on // PCIe), if any, // - Followed by followed by the list of devices we ship. - // Only probed devices will be marked with .present == 1. + // Only probed devices will be marked with .present == true. // // In the end this calls back into acl_init_platform which also sets // acl_platform.initialized = 1. @@ -302,15 +301,9 @@ void acl_init_platform(void) { acl_platform.cl_obj_head = 0; // Set offline_device property - const char *offline_device = - acl_get_offline_device_user_setting(&acl_platform.offline_mode); - if (offline_device) { - if (acl_platform.offline_mode == ACL_CONTEXT_MPSIM) { - acl_platform.offline_device = ACL_MPSIM_DEVICE_NAME; - } else { - acl_platform.offline_device = offline_device; - } - } + std::string offline_device = ""; + acl_platform.offline_mode = + acl_get_offline_device_user_setting(&offline_device); acl_platform.name = "Intel(R) FPGA SDK for OpenCL(TM)"; acl_platform.vendor = "Intel(R) Corporation"; @@ -386,8 +379,9 @@ void acl_init_platform(void) { case ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY: acl_platform.num_devices = acl_platform.initial_board_def->num_devices + - (offline_device ? 1 : 0); // the devices in the board def + 1 for the - // offline device, if it exists + (offline_device.empty() ? 0 + : 1); // the devices in the board def + 1 for + // the offline device, if it exists break; case ACL_CONTEXT_MPSIM: #ifdef __linux__ @@ -408,7 +402,7 @@ void acl_init_platform(void) { l_add_device(static_cast(i)); } - l_initialize_offline_devices(acl_platform.offline_mode); + l_initialize_offline_devices(offline_device); // Device operation queue. acl_init_device_op_queue(&acl_platform.device_op_queue); @@ -519,8 +513,7 @@ void acl_finalize_init_platform(unsigned int num_devices, acl_assert_locked(); assert(num_devices > 0); - l_initialize_devices(acl_present_board_def(), acl_platform.offline_mode, - num_devices, devices); + l_initialize_devices(acl_present_board_def(), num_devices, devices); if (is_SOC_device()) { size_t cur_num_banks = @@ -565,7 +558,7 @@ static void l_show_devs(const char *prefix) { } } -static void l_initialize_offline_devices(int offline_mode) { +static void l_initialize_offline_devices(std::string offline_device) { acl_platform.global_mem.range.begin = 0; acl_platform.global_mem.range.next = 0; @@ -592,7 +585,7 @@ static void l_initialize_offline_devices(int offline_mode) { board_def->num_devices = 1; } - if (offline_mode == ACL_CONTEXT_MPSIM) { + if (acl_platform.offline_mode == ACL_CONTEXT_MPSIM) { auto &board_def = shipped_board_defs.emplace_back(); board_def.emplace(); std::string err_msg; @@ -607,37 +600,48 @@ static void l_initialize_offline_devices(int offline_mode) { } } - if (!acl_platform.offline_device.empty()) { + if (!offline_device.empty()) { unsigned int board_count = 1; int device_index = 0; - if (offline_mode == ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY) { + if (acl_platform.offline_mode == ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY) { // In this case, we place the offline device at the end of the device list // (after the autodiscovered devices). device_index = (int)(acl_platform.num_devices - board_count); } + const bool is_present = (acl_platform.offline_mode == ACL_CONTEXT_MPSIM); // If the user specified an offline device, then load it. // Search the shipped board defs for the device: for (const auto &board_def : shipped_board_defs) { if (!board_def.has_value()) continue; - if (acl_platform.offline_device != - board_def->device[0].autodiscovery_def.name) + + // Currently we either have a single simulator device or a single + // offline device, so bail early if device name doesn't match + if (offline_device != board_def->device[0].autodiscovery_def.name) continue; - const bool is_present = (offline_mode == ACL_CONTEXT_MPSIM); for (unsigned j = 0; j < board_count; j++) { // Bail if not present and we haven't been told to use absent devices - if (!is_present && acl_platform.offline_device != - board_def->device[0].autodiscovery_def.name) + // In future, need to index offline_device with j when multiple + // simulator devices are supported + if (!is_present && + offline_device != board_def->device[0].autodiscovery_def.name) continue; // Add HW specific device definition acl_platform.device[device_index].def = board_def->device[0]; // Struct Copy acl_platform.device[device_index].present = is_present; + acl_platform.device[device_index].offline = !is_present; + if (!is_present) + acl_platform.has_offline_device = 1; device_index++; } } + if (!is_present && acl_platform.has_offline_device == 0) { + // Did not find specified offline device in the shipped board defs + acl_platform.has_offline_device = -1; + } } l_show_devs("offline"); } @@ -645,28 +649,25 @@ static void l_initialize_offline_devices(int offline_mode) { // Initialize acl_platform with device information. // Also determine global mem address range. static void l_initialize_devices(const acl_system_def_t *present_board_def, - int offline_mode, unsigned int num_devices, + unsigned int num_devices, const cl_device_id *devices) { unsigned int i, j; acl_assert_locked(); - acl_print_debug_msg("\n\nReset device list: %d\n", offline_mode); + acl_print_debug_msg("\n\nReset device list: %d\n", + acl_platform.offline_mode); if (present_board_def) { acl_print_debug_msg("\n\nPresent board def: %d\n", present_board_def->num_devices); } - // shipped_board_def populated earlier in l_initialize_offline_devices - - if (offline_mode == ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY || - offline_mode == ACL_CONTEXT_MSIM || offline_mode == ACL_CONTEXT_MPSIM) { + if (acl_platform.offline_mode != ACL_CONTEXT_OFFLINE_ONLY) { unsigned int num_platform_devices = acl_platform.num_devices; - if (!acl_platform.offline_device.empty() && - offline_mode != ACL_CONTEXT_MSIM && offline_mode != ACL_CONTEXT_MPSIM) { - num_platform_devices -= - 1; // In this case there's an extra offline devices at the end of the - // list. Do not check it. + if (acl_platform.has_offline_device == 1) { + // There's an extra offline devices at the end of the list, Do not check + // it. + num_platform_devices -= 1; } // Then add the present devices, if any. @@ -687,7 +688,7 @@ static void l_initialize_devices(const acl_system_def_t *present_board_def, if (acl_platform.device[i].opened_count == 1) { acl_platform.device[i].def = present_board_def->device[i]; // Struct copy. - acl_platform.device[i].present = 1; + acl_platform.device[i].present = true; } break; } @@ -724,6 +725,7 @@ static void l_add_device(int idx) { device->min_local_mem_size = 16 * 1024; // Min value for OpenCL full profile. device->address_bits = 64; // Yes, our devices are 64-bit. + device->offline = false; // Not an offline device by default } // These functions check to see if a given object is known to the system. diff --git a/test/acl_command_queue_test.cpp b/test/acl_command_queue_test.cpp index fddcf914..22ff0cee 100644 --- a/test/acl_command_queue_test.cpp +++ b/test/acl_command_queue_test.cpp @@ -52,9 +52,8 @@ MT_TEST_GROUP(acl_command_queue) { CHECK_EQUAL(CL_SUCCESS, clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, MAX_DEVICES, &m_device[0], &m_num_devices)); - int offline_only = 0; - CHECK_EQUAL(0, acl_get_offline_device_user_setting(&offline_only)); - CHECK_EQUAL(0, offline_only); + CHECK_EQUAL(ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY, + acl_get_offline_device_user_setting(NULL)); CHECK(m_num_devices > 0); }