GQueue* prefetch_segments(segmentid id, int prefetch_num) { static struct backupVersion *opened_bv; if (id == TEMPORARY_ID) { assert(id != TEMPORARY_ID); return NULL; } int64_t bnum = id_to_bnum(id); int64_t off = id_to_off(id); int64_t size = id_to_size(id); /* All prefetched segment recipes */ GQueue *segments = g_queue_new(); if(opened_bv == NULL || opened_bv->bv_num != bnum){ /* The required segment locates in another backup */ if(opened_bv && opened_bv->bv_num != jcr.bv->bv_num) free_backup_version(opened_bv); if(bnum == jcr.bv->bv_num) opened_bv = jcr.bv; else{ opened_bv = open_backup_version(bnum); assert(opened_bv); } } fseek(opened_bv->recipe_fp, off, SEEK_SET); VERBOSE("Dedup phase: Read segment %lld in backup %lld of %lld offset and %lld size", id, bnum, off, size); struct chunkPointer flag; int j; for (j = 0; j < prefetch_num; j++) { int64_t current_off = ftell(opened_bv->recipe_fp); fread(&flag.fp, sizeof(flag.fp), 1, opened_bv->recipe_fp); fread(&flag.id, sizeof(flag.id), 1, opened_bv->recipe_fp); fread(&flag.size, sizeof(flag.size), 1, opened_bv->recipe_fp); if(flag.id != -CHUNK_SEGMENT_START){ VERBOSE("Dedup phase: no more segment can be prefetched at offset %lld!", current_off); assert(j!=0); break; } struct segmentRecipe* sr = new_segment_recipe(); sr->id = make_segment_id(opened_bv->bv_num, current_off, flag.size); int i; for (i = 0; i < flag.size; i++) { struct chunkPointer* cp = (struct chunkPointer*) malloc( sizeof(struct chunkPointer)); fread(&cp->fp, sizeof(cp->fp), 1, opened_bv->recipe_fp); fread(&cp->id, sizeof(cp->id), 1, opened_bv->recipe_fp); fread(&cp->size, sizeof(cp->size), 1, opened_bv->recipe_fp); if(cp->id <= TEMPORARY_ID){ WARNING("expect > 0, but being %lld", cp->id); assert(cp->id > TEMPORARY_ID); } g_hash_table_replace(sr->kvpairs, &cp->fp, cp); } fread(&flag.fp, sizeof(flag.fp), 1, opened_bv->recipe_fp); fread(&flag.id, sizeof(flag.id), 1, opened_bv->recipe_fp); fread(&flag.size, sizeof(flag.size), 1, opened_bv->recipe_fp); assert(flag.id == 0 - CHUNK_SEGMENT_END); g_queue_push_tail(segments, sr); } return segments; }
void compute(int rank, int size) { double *row1a = (double *) malloc(sizeof(double) * size_x); double *row1b = (double *) malloc(sizeof(double) * size_x); memset(row1a, 0, sizeof(double *) * size_x); double *row2a = (double *) malloc(sizeof(double) * size_x); double *row2b = (double *) malloc(sizeof(double) * size_x); memset(row2a, 0, sizeof(double *) * size_x); int position = id_to_position(size_y, size, rank); int height = id_to_size(size_y, size, rank); MPI_Request req[2]; MPI_Request req2[2]; DoubleMatrix matrix(size_x, height); set_fixed_temp(matrix, size_y, position, temp); matrix.swap(); compute_new_values(matrix, row1a, row2a); set_fixed_temp(matrix, size_y, position, temp); matrix.swap(); for (int i = 1; i < iterations; i++) { MPI_Isend(row1a, size_x, MPI_DOUBLE, (rank + size - 1) % size, TAG_ROW1, MPI_COMM_WORLD, &req[0]); MPI_Isend(row2a, size_x, MPI_DOUBLE, (rank + 1) % size, TAG_ROW2, MPI_COMM_WORLD, &req[1]); MPI_Irecv(row1b, size_x, MPI_DOUBLE, (rank + size - 1) % size, TAG_ROW2, MPI_COMM_WORLD, &req2[0]); MPI_Irecv(row2b, size_x, MPI_DOUBLE, (rank + 1) % size, TAG_ROW1, MPI_COMM_WORLD, &req2[1]); MPI_Waitall(2, req2, MPI_STATUSES_IGNORE); double *tmp; tmp = row1a; // swap row1a <-> row1b row1a = row1b; row1b = tmp; tmp = row2a; // swap row2a <-> row2b row2a = row2b; row2b = tmp; compute_new_values(matrix, row1a, row2a); set_fixed_temp(matrix, size_y, position, temp); matrix.swap(); MPI_Waitall(2, req, MPI_STATUSES_IGNORE); } free(row1a); free(row1b); free(row2a); free(row2b); if (rank == 0) { DoubleMatrix out(size_x, size_y); out.set_data(matrix.get_data(), size_x * position, matrix.get_data_size()); for (int rank = 1; rank < size; rank++) { int position = id_to_position(size_y, size, rank); int height = id_to_size(size_y, size, rank); MPI_Recv(out.get_write_pointer(0, position), size_x * height, MPI_DOUBLE, rank, TAG_MATRIX, MPI_COMM_WORLD, MPI_STATUSES_IGNORE); } out.swap(); out.write_to_file("result2.html"); } else { MPI_Send(matrix.get_data(), matrix.get_size_x() * matrix.get_size_y(), MPI_DOUBLE, 0, TAG_MATRIX, MPI_COMM_WORLD); } }