/* Only get here if we think we have Berkeley type signals so we can look at a second argument to fpe_catch() to get the reason for an exception */ static void get_fpe_codes(void) { int divz = 0; int ovf = 0; may_be_safe_to_look_at_why = 1; if (setjmp(jbuff) == 0) div_by(1000.0, 0.0); else { divz = why_v; catch_FPEs(); } if (setjmp(jbuff) == 0) overflow(1000.0); else { ovf = why_v; catch_FPEs(); } /* make some guesses if sane values */ if (divz > 0 && ovf > 0 && divz != ovf) { printf("X FPE_ZERODIVIDE %d\n", divz); printf("X FPE_OVERFLOW %d\n", ovf); exit(0); } else exit(1); }
static void check_fpe_traps(void) { int traps = 0; if (setjmp(jbuff) == 0) { div_by(44.0, 0.0); message("division by zero does not generate an exception"); } else { traps = 1; message("division by zero generates an exception"); catch_FPEs(); /* set again if sysV */ } if (setjmp(jbuff) == 0) { overflow(1000.0); message("overflow does not generate an exception"); } else { traps |= 2; message("overflow generates an exception"); catch_FPEs(); } if (traps == 0) { double maybe_nan; maybe_nan = sqrt(-8.0); if (is_nan(maybe_nan)) { message("math library supports ieee754"); } else { traps |= 4; message("math library does not support ieee754"); } } exit(traps); }
int _kmeans(double **data, double **centroids, int *membership, \ double *inertia, int rank, int size, int *ppp, mytimer *t, options opt) { timestamp_type time_is, time_ie; timestamp_type time_cs, time_ce; #ifdef TIME_ALL timestamp_type comm_s, comm_e; #endif double dist, total_inertia, total_delta, delta = (double) opt.n_points; int i, center, iters = 0; // allocate for new centroids that will be computed double **new_centers = (double**) alloc2d(opt.n_centroids, opt.dimensions); memset(*new_centers, 0, opt.n_centroids * opt.dimensions * sizeof(double)); // allocate array to count points in each cluster, initialize to 0 int *count_centers = (int*) calloc(opt.n_centroids, sizeof(int)); check(count_centers); int *new_count_centers = (int*) calloc(opt.n_centroids, sizeof(int)); check(new_count_centers); // if a cluster has 0 points assigned use this for random reinitialization double *point = (double*) malloc(opt.dimensions * sizeof(double)); check(point); double *tofree = point; get_timestamp(&time_is); t->comm_time += initialize(data, centroids, ppp, rank, size, opt); get_timestamp(&time_ie); #ifdef TIME_ALL get_timestamp(&comm_s); #endif MPI_Bcast(*centroids, opt.n_centroids*opt.dimensions, MPI_DOUBLE, 0, MPI_COMM_WORLD); #ifdef TIME_ALL get_timestamp(&comm_e); t->comm_time += timestamp_diff_in_seconds(comm_s, comm_e); #endif get_timestamp(&time_cs); while (delta / ((double) opt.n_points) > opt.tol && iters < opt.max_iter) { // MPI_Barrier(MPI_COMM_WORLD); delta = 0.0; *inertia = 0.0; for(i = 0; i < opt.local_rows; i++){ find_nearest_centroid(data[i], centroids, opt, ¢er, &dist); *inertia += dist; if (membership[i] != center) { delta++; membership[i] = center; } add(new_centers[center], data[i], opt); new_count_centers[center]++; } #ifdef TIME_ALL get_timestamp(&comm_s); #endif MPI_Allreduce(*new_centers, *centroids, opt.n_centroids * opt.dimensions, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(new_count_centers, count_centers, opt.n_centroids, MPI_INT, MPI_SUM, MPI_COMM_WORLD); #ifdef TIME_ALL get_timestamp(&comm_e); t->comm_time += timestamp_diff_in_seconds(comm_s, comm_e); #endif for(i = 0; i < opt.n_centroids; i++) { if(count_centers[i] == 0) { if(rank == 0){ add(centroids[i], data[randint(opt.local_rows)], opt); } // broadcast this new point to everyone #ifdef TIME_ALL get_timestamp(&comm_s); #endif MPI_Bcast(centroids[i], opt.dimensions, MPI_DOUBLE, 0, MPI_COMM_WORLD); #ifdef TIME_ALL get_timestamp(&comm_e); t->comm_time += timestamp_diff_in_seconds(comm_s, comm_e); #endif // add to delta to ensure we dont stop after this delta += opt.tol * opt.local_rows + 1.0; } // all good to divide, count is not 0 else { // calculate the new center div_by(centroids[i], count_centers[i], opt); } } // sum up the number of cluster assignments that changed #ifdef TIME_ALL get_timestamp(&comm_s); #endif MPI_Allreduce(&delta, &total_delta, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); delta = total_delta; // sum up the inertias MPI_Allreduce(inertia, &total_inertia, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); *inertia = total_inertia; #ifdef TIME_ALL get_timestamp(&comm_e); t->comm_time += timestamp_diff_in_seconds(comm_s, comm_e); #endif // zero out new_centers and count_centers memset(*new_centers, 0, opt.n_centroids * opt.dimensions * sizeof(double)); memset(new_count_centers, 0, opt.n_centroids * sizeof(int)); memset(count_centers, 0, opt.n_centroids * sizeof(int)); iters++; if(opt.verbose > 1 && rank == 0) { printf("\n\titers: %d\n", iters); printf("\tdelta: %d\n", (int) delta); printf("\teps: %f\n", delta / ((double) opt.n_points)); printf("\tinertia: %f\n", *inertia); } } get_timestamp(&time_ce); t->init_time += timestamp_diff_in_seconds(time_is, time_ie); t->comp_time += timestamp_diff_in_seconds(time_cs, time_ce); free(*new_centers); free(new_centers); free(count_centers); free(new_count_centers); free(tofree); if(iters == opt.max_iter && rank == 0 && opt.verbose > 0) { printf("HIT MAX ITERS\n"); } return iters; }