extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE( TARGET_TYPE target_type, int target_number, int is_optional, _Offload_status* status, const char* file, uint64_t line ) { bool retval; OFFLOAD ofld; // initialize status if (status != 0) { status->result = OFFLOAD_UNAVAILABLE; status->device_number = -1; status->data_sent = 0; status->data_received = 0; } // make sure libray is initialized retval = __offload_init_library(); // OFFLOAD_TIMER_INIT must follow call to __offload_init_library OffloadHostTimerData * timer_data = OFFLOAD_TIMER_INIT(file, line); OFFLOAD_TIMER_START(timer_data, c_offload_host_total_offload); OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize); // initialize all devices is init_type is on_offload_all if (retval && __offload_init_type == c_init_on_offload_all) { for (int i = 0; i < mic_engines_total; i++) { mic_engines[i].init(); } } OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize); OFFLOAD_TIMER_START(timer_data, c_offload_host_target_acquire); if (target_type == TARGET_HOST) { // Host always available retval = true; } else if (target_type == TARGET_MIC) { if (target_number >= -1) { if (retval) { if (target_number >= 0) { // User provided the device number target_number = target_number % mic_engines_total; } else { // use device 0 target_number = 0; } // reserve device in ORSL if (is_optional) { if (!ORSL::try_reserve(target_number)) { target_number = -1; } } else { if (!ORSL::reserve(target_number)) { target_number = -1; } } // initialize device if (target_number >= 0 && __offload_init_type == c_init_on_offload) { OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize); mic_engines[target_number].init(); OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize); } } else { // fallback to CPU target_number = -1; } if (target_number < 0 || !retval) { if (!is_optional && status == 0) { LIBOFFLOAD_ERROR(c_device_is_not_available); exit(1); } retval = false; } } else { LIBOFFLOAD_ERROR(c_invalid_device_number); exit(1); } } if (retval) { ofld = new OffloadDescriptor(target_number, status, !is_optional, false, timer_data); OFFLOAD_TIMER_HOST_MIC_NUM(timer_data, target_number); Offload_Report_Prolog(timer_data); OFFLOAD_DEBUG_TRACE_1(2, timer_data->offload_number, c_offload_start, "Starting offload: target_type = %d, " "number = %d, is_optional = %d\n", target_type, target_number, is_optional); OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire); } else { ofld = NULL; OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire); OFFLOAD_TIMER_STOP(timer_data, c_offload_host_total_offload); offload_report_free_data(timer_data); } return ofld; }
void OffloadDescriptor::offload( uint32_t buffer_count, void** buffers, void* misc_data, uint16_t misc_data_len, void* return_data, uint16_t return_data_len ) { FunctionDescriptor *func = (FunctionDescriptor*) misc_data; const char *name = func->data; OffloadDescriptor ofld; char *in_data = 0; char *out_data = 0; char *timer_data = 0; console_enabled = func->console_enabled; timer_enabled = func->timer_enabled; offload_report_level = func->offload_report_level; offload_number = func->offload_number; ofld.set_offload_number(func->offload_number); #ifdef SEP_SUPPORT if (sep_monitor) { if (__sync_fetch_and_add(&sep_counter, 1) == 0) { OFFLOAD_DEBUG_TRACE(2, "VTResumeSampling\n"); VTResumeSampling(); } } #endif // SEP_SUPPORT OFFLOAD_DEBUG_TRACE_1(2, ofld.get_offload_number(), c_offload_start_target_func, "Offload \"%s\" started\n", name); // initialize timer data OFFLOAD_TIMER_INIT(); OFFLOAD_TIMER_START(c_offload_target_total_time); OFFLOAD_TIMER_START(c_offload_target_descriptor_setup); // get input/output buffer addresses if (func->in_datalen > 0 || func->out_datalen > 0) { if (func->data_offset != 0) { in_data = (char*) misc_data + func->data_offset; out_data = (char*) return_data; } else { char *inout_buf = (char*) buffers[--buffer_count]; in_data = inout_buf; out_data = inout_buf; } } // assign variable descriptors ofld.m_vars_total = func->vars_num; if (ofld.m_vars_total > 0) { uint64_t var_data_len = ofld.m_vars_total * sizeof(VarDesc); ofld.m_vars = (VarDesc*) malloc(var_data_len); if (ofld.m_vars == NULL) LIBOFFLOAD_ERROR(c_malloc); memcpy(ofld.m_vars, in_data, var_data_len); in_data += var_data_len; func->in_datalen -= var_data_len; } // timer data if (func->timer_enabled) { uint64_t timer_data_len = OFFLOAD_TIMER_DATALEN(); timer_data = out_data; out_data += timer_data_len; func->out_datalen -= timer_data_len; } // init Marshallers ofld.m_in.init_buffer(in_data, func->in_datalen); ofld.m_out.init_buffer(out_data, func->out_datalen); // copy buffers to offload descriptor std::copy(buffers, buffers + buffer_count, std::back_inserter(ofld.m_buffers)); OFFLOAD_TIMER_STOP(c_offload_target_descriptor_setup); // find offload entry address OFFLOAD_TIMER_START(c_offload_target_func_lookup); offload_func_with_parms entry = (offload_func_with_parms) __offload_entries.find_addr(name); if (entry == NULL) { #if OFFLOAD_DEBUG > 0 if (console_enabled > 2) { __offload_entries.dump(); } #endif LIBOFFLOAD_ERROR(c_offload_descriptor_offload, name); exit(1); } OFFLOAD_TIMER_STOP(c_offload_target_func_lookup); OFFLOAD_TIMER_START(c_offload_target_func_time); // execute offload entry entry(&ofld); OFFLOAD_TIMER_STOP(c_offload_target_func_time); OFFLOAD_TIMER_STOP(c_offload_target_total_time); // copy timer data to the buffer OFFLOAD_TIMER_TARGET_DATA(timer_data); OFFLOAD_DEBUG_TRACE(2, "Offload \"%s\" finished\n", name); #ifdef SEP_SUPPORT if (sep_monitor) { if (__sync_sub_and_fetch(&sep_counter, 1) == 0) { OFFLOAD_DEBUG_TRACE(2, "VTPauseSampling\n"); VTPauseSampling(); } } #endif // SEP_SUPPORT }
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE1( const int* device_num, const char* file, uint64_t line ) { int target_number; // make sure libray is initialized and at least one device is available if (!__offload_init_library()) { LIBOFFLOAD_ERROR(c_device_is_not_available); exit(1); } // OFFLOAD_TIMER_INIT must follow call to __offload_init_library OffloadHostTimerData * timer_data = OFFLOAD_TIMER_INIT(file, line); OFFLOAD_TIMER_START(timer_data, c_offload_host_total_offload); OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize); if (__offload_init_type == c_init_on_offload_all) { for (int i = 0; i < mic_engines_total; i++) { mic_engines[i].init(); } } OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize); OFFLOAD_TIMER_START(timer_data, c_offload_host_target_acquire); // use default device number if it is not provided if (device_num != 0) { target_number = *device_num; } else { target_number = __omp_device_num; } // device number should be a non-negative integer value if (target_number < 0) { LIBOFFLOAD_ERROR(c_omp_invalid_device_num); exit(1); } // should we do this for OpenMP? target_number %= mic_engines_total; // reserve device in ORSL if (!ORSL::reserve(target_number)) { LIBOFFLOAD_ERROR(c_device_is_not_available); exit(1); } // initialize device(s) OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize); if (__offload_init_type == c_init_on_offload) { mic_engines[target_number].init(); } OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize); OFFLOAD ofld = new OffloadDescriptor(target_number, 0, true, true, timer_data); OFFLOAD_TIMER_HOST_MIC_NUM(timer_data, target_number); Offload_Report_Prolog(timer_data); OFFLOAD_DEBUG_TRACE_1(2, timer_data->offload_number, c_offload_start, "Starting OpenMP offload, device = %d\n", target_number); OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire); return ofld; }