| 8 | using namespace svm_kernel; |
| 9 | |
| 10 | void |
| 11 | CSMOSolver::solve(const KernelMatrix &k_mat, const SyncArray<int> &y, SyncArray<float_type> &alpha, float_type &rho, |
| 12 | SyncArray<float_type> &f_val, float_type eps, float_type Cp, float_type Cn, int ws_size, |
| 13 | int out_max_iter) const { |
| 14 | int n_instances = k_mat.n_instances(); |
| 15 | int q = ws_size / 2; |
| 16 | |
| 17 | SyncArray<int> working_set(ws_size); |
| 18 | SyncArray<int> working_set_first_half(q); |
| 19 | SyncArray<int> working_set_last_half(q); |
| 20 | #ifdef USE_CUDA |
| 21 | working_set_first_half.set_device_data(working_set.device_data()); |
| 22 | working_set_last_half.set_device_data(&working_set.device_data()[q]); |
| 23 | #endif |
| 24 | working_set_first_half.set_host_data(working_set.host_data()); |
| 25 | working_set_last_half.set_host_data(&working_set.host_data()[q]); |
| 26 | |
| 27 | SyncArray<int> f_idx(n_instances); |
| 28 | SyncArray<int> f_idx2sort(n_instances); |
| 29 | SyncArray<float_type> f_val2sort(n_instances); |
| 30 | SyncArray<float_type> alpha_diff(ws_size); |
| 31 | SyncArray<float_type> diff(2); |
| 32 | |
| 33 | SyncArray<kernel_type> k_mat_rows(ws_size * k_mat.n_instances()); |
| 34 | SyncArray<kernel_type> k_mat_rows_first_half(q * k_mat.n_instances()); |
| 35 | SyncArray<kernel_type> k_mat_rows_last_half(q * k_mat.n_instances()); |
| 36 | #ifdef USE_CUDA |
| 37 | k_mat_rows_first_half.set_device_data(k_mat_rows.device_data()); |
| 38 | k_mat_rows_last_half.set_device_data(&k_mat_rows.device_data()[q * k_mat.n_instances()]); |
| 39 | #else |
| 40 | k_mat_rows_first_half.set_host_data(k_mat_rows.host_data()); |
| 41 | k_mat_rows_last_half.set_host_data(&k_mat_rows.host_data()[q * k_mat.n_instances()]); |
| 42 | #endif |
| 43 | int *f_idx_data = f_idx.host_data(); |
| 44 | for (int i = 0; i < n_instances; ++i) { |
| 45 | f_idx_data[i] = i; |
| 46 | } |
| 47 | init_f(alpha, y, k_mat, f_val); |
| 48 | LOG(INFO) << "training start"; |
| 49 | int max_iter = max(100000, ws_size > INT_MAX / 100 ? INT_MAX : 100 * ws_size); |
| 50 | long long local_iter = 0; |
| 51 | |
| 52 | //avoid infinite loop of repeated local diff |
| 53 | int same_local_diff_cnt = 0; |
| 54 | float_type previous_local_diff = INFINITY; |
| 55 | int swap_local_diff_cnt = 0; |
| 56 | float_type last_local_diff = INFINITY; |
| 57 | float_type second_last_local_diff = INFINITY; |
| 58 | |
| 59 | for (int iter = 0;; ++iter) { |
| 60 | //select working set |
| 61 | f_idx2sort.copy_from(f_idx); |
| 62 | f_val2sort.copy_from(f_val); |
| 63 | sort_f(f_val2sort, f_idx2sort); |
| 64 | vector<int> ws_indicator(n_instances, 0); |
| 65 | if (0 == iter) { |
| 66 | select_working_set(ws_indicator, f_idx2sort, y, alpha, Cp, Cn, working_set); |
| 67 | k_mat.get_rows(working_set, k_mat_rows); |
no test coverage detected