int main(void) { const char *signal_file = "../data/input.csv"; double *signals; int signal_length; const char *filter_file = "../data/filter.csv"; double *filter; int filter_length; double *products; int i; // ファイルから読み込む get_double_data(filter_file, filter, &filter_length); get_double_data(signal_file, signals, &signal_length); // 畳み込みの実行 convolute(filter, filter_length, signals, signal_length, products); // 出力する printf("\nSIGNALS:\n"); for(i = 0; i < signal_length; i++) { printf("%d:\t%f\n", i, signals[i]); } printf("\nFILTER:\n"); for(i = 0; i < signal_length; i++) { printf("%d:\t%f\n", i, filter[i]); } printf("\nOUTPUT:\n"); for(i = 0; i < signal_length - filter_length; i++) { printf("%d:\t%f\n", i, products[i]); } }
template<class Out, class T> Out Convolution<Out, T>::operator()(T t, void* args) { if(m_product_function == NULL) return 0; ((Affine_function<Out, T>*)m_product_function->get_f2()->get_f2())->set_t_shift(-t); return convolute(m_integrator, m_product_function, t, args, m_t_inf, m_t_sup, m_fixed_interval); }
int main(int argc, char* argv[] ) { init(); convolute(); return 0; }
PNM* BlurGaussian::transform() { emit message("Blurring..."); int size = getParameter("size").toInt(); radius = (size/2)+1; sigma = getParameter("sigma").toDouble(); return convolute(getMask(size, Normalize), RepeatEdge); }
//uses is_correctible instead of the actual reed_solomon codec to make it faster float message_pass_rate_sim(int num_errors_min, int tries_max, float BER, int t) { int successes = 0; int errors = 0; int tries = 0; while(errors < num_errors_min) { raw_data rd; rd.length = 128 + 2*t; rd.data = (uint8_t*)alloc_named(rd.length, "message_pass_rate_sim rd"); unsigned int i; for(i = 0; i < rd.length; i++) rd.data[i] = rand(); raw_data ep = convolute(rd); //interleaving not needed as errror insertion is AWGN- faster to not do it //interleave(ep); //interleaves data in place insert_errors2(ep.data, ep.length, BER); //deinterleave(ep); raw_data deconvoluted = deconvolute(ep, NULL); if(is_correctible(rd, deconvoluted, t, 0)) { successes++; } else { errors++; } dealloc(ep.data); dealloc(deconvoluted.data); dealloc(rd.data); if(tries >= tries_max) break; tries++; } return (float)successes / ((float)successes + (float)errors); }
/** Returns a convoluted form of the image */ PNM* Convolution::transform() { return convolute(getMask(3, Normalize), RepeatEdge); }
T operator()(const T * py) const { return convolute(py); }
template<class Out, class T> Out Convolution<Out, T>::convolute(Integration<Out, T>* integrator, Function_class<Out, T>* f1, Function_class<Out, T>* f2, T t, void* args, T t_inf, T t_sup, bool fixed_interval) { return convolute(integrator, (*f1) * ((*f2)(Affine_function<Out, T>(1, -t))), t, args, t_inf, t_sup, fixed_interval); }
template<class Out, class T> Out Convolution<Out, T>::operator()(Function_class<Out, T>* f1, Function_class<Out, T>* f2, T t, void* args) { return convolute(m_integrator, f1, f2, t, args, m_t_inf, m_t_sup, m_fixed_interval); }
void Tilemap::generateLevel() { int* ceiling = new int[GRID_SIZE_X]; int* floor = new int[GRID_SIZE_X]; for(int x=0; x<GRID_SIZE_X; x++) { if(x < 16) { ceiling[x] = 4; floor[x] = 4; continue; } ceiling[x] = rand() % int(GRID_SIZE_Y*0.4f); floor[x] = 1 + rand() % int(GRID_SIZE_Y*0.4f); if(rand() % 10 == 1) ceiling[x] += 5; else if(rand() % 10 == 1) floor[x] += 5; } float* tent = generateTentKernel(1.f); ceiling = convolute(ceiling, GRID_SIZE_X, tent, 8); tent = generateTentKernel(1.f); floor = convolute(floor, GRID_SIZE_X, tent, 8); float* box = generateBoxKernel(); ceiling = convolute(ceiling, GRID_SIZE_X, box, 4); box = generateBoxKernel(); floor = convolute(floor, GRID_SIZE_X, box, 4); for(int x=0; x<GRID_SIZE_X; x++) { for(int y=0; y<ceiling[x]; y++) { if(rand() % 10 == 1) grid[x][y] = 1 + rand() % 3; else grid[x][y] = 1; } } for(int x=0; x<GRID_SIZE_X; x++) { for(int y=0; y<floor[x]; y++) { if(rand() % 10 == 1) grid[x][GRID_SIZE_Y-y] = 1 + rand() % 3; else grid[x][GRID_SIZE_Y-y] = 1; } } // edge detection for(int y=0; y<GRID_SIZE_Y; y++) for(int x=0; x<GRID_SIZE_X; x++) { int ri = rand() % 3; if(grid[x][y] > 0) { int neighborA = 0, neighborB = 0, neighborC = 0, neighborD = 0; if(y-1 < 0) neighborA = 1; else neighborA = grid[x][y-1]; if(x+1 >= GRID_SIZE_X) neighborB = 1; else neighborB = grid[x+1][y]; if(y+1 >= GRID_SIZE_Y) neighborC = 1; else neighborC = grid[x][y+1]; if(x-1 < 0) neighborD = 1; else neighborD = grid[x-1][y]; if(neighborA && neighborB && !neighborC && !neighborD) { if(ri == 0) { grid[x][y] = 4; } else if(ri == 1) { grid[x][y] = 8; } else { grid[x][y] = 12; } } else if(neighborA && !neighborB && !neighborC && neighborD) { if(ri == 0) { grid[x][y] = 5; } else if(ri == 1) { grid[x][y] = 9; } else { grid[x][y] = 13; } } else if(!neighborA && neighborB && neighborC && !neighborD) { if(ri == 0) { grid[x][y] = 6; } else if(ri == 1) { grid[x][y] = 10; } else { grid[x][y] = 14; } } else if(!neighborA && !neighborB && neighborC && neighborD) { if(ri == 0) { grid[x][y] = 7; } else if(ri == 1) { grid[x][y] = 11; } else { grid[x][y] = 15; } } else if(!neighborA) { if(rand() % 10 == 1) grid[x][y] = 17; else grid[x][y] = 16; } else if(!neighborC) { if(rand() % 10 == 1) grid[x][y] = 19; else grid[x][y] = 18; } } } }
int main(int argc, char** argv) { int thread_count = 4; int fd, i, j, k, width, height, loops, t, row_div, col_div, rows, cols; double timer, remote_time; char *image; color_t imageType; /* MPI world topology */ int process_id, num_processes; /* Find current task id */ MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &num_processes); MPI_Comm_rank(MPI_COMM_WORLD, &process_id); /* MPI status */ MPI_Status status; /* MPI data types */ MPI_Datatype grey_col_type; MPI_Datatype rgb_col_type; MPI_Datatype grey_row_type; MPI_Datatype rgb_row_type; /* MPI requests */ MPI_Request send_north_req; MPI_Request send_south_req; MPI_Request send_west_req; MPI_Request send_east_req; MPI_Request recv_north_req; MPI_Request recv_south_req; MPI_Request recv_west_req; MPI_Request recv_east_req; /* Neighbours */ int north = -1; int south = -1; int west = -1; int east = -1; /* Check arguments */ if (process_id == 0) { Usage(argc, argv, &image, &width, &height, &loops, &imageType); /* Division of data in each process */ row_div = divide_rows(height, width, num_processes); if (row_div <= 0 || height % row_div || num_processes % row_div || width % (col_div = num_processes / row_div)) { fprintf(stderr, "%s: Cannot divide to processes\n", argv[0]); MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); return EXIT_FAILURE; } } if (process_id != 0) { image = malloc((strlen(argv[1])+1) * sizeof(char)); strcpy(image, argv[1]); } /* Broadcast parameters */ MPI_Bcast(&width, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&height, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&loops, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&imageType, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&row_div, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&col_div, 1, MPI_INT, 0, MPI_COMM_WORLD); /* Compute number of rows per process */ rows = height / row_div; cols = width / col_div; /* Create column data type for grey & rgb */ MPI_Type_vector(rows, 1, cols+2, MPI_BYTE, &grey_col_type); MPI_Type_commit(&grey_col_type); MPI_Type_vector(rows, 3, 3*cols+6, MPI_BYTE, &rgb_col_type); MPI_Type_commit(&rgb_col_type); /* Create row data type */ MPI_Type_contiguous(cols, MPI_BYTE, &grey_row_type); MPI_Type_commit(&grey_row_type); MPI_Type_contiguous(3*cols, MPI_BYTE, &rgb_row_type); MPI_Type_commit(&rgb_row_type); /* Compute starting row and column */ int start_row = (process_id / col_div) * rows; int start_col = (process_id % col_div) * cols; /* Init filters */ int box_blur[3][3] = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}; int gaussian_blur[3][3] = {{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}; int edge_detection[3][3] = {{1, 4, 1}, {4, 8, 4}, {1, 4, 1}}; float **h = malloc(3 * sizeof(float *)); for (i = 0 ; i < 3 ; i++) h[i] = malloc(3 * sizeof(float)); for (i = 0 ; i < 3 ; i++) { for (j = 0 ; j < 3 ; j++){ // h[i][j] = box_blur[i][j] / 9.0; h[i][j] = gaussian_blur[i][j] / 16.0; // h[i][j] = edge_detection[i][j] / 28.0; } } /* Init arrays */ uint8_t *src = NULL, *dst = NULL, *tmpbuf = NULL, *tmp = NULL; MPI_File fh; int filesize, bufsize, nbytes; if (imageType == GREY) { filesize = width * height; bufsize = filesize / num_processes; nbytes = bufsize / sizeof(uint8_t); src = calloc((rows+2) * (cols+2), sizeof(uint8_t)); dst = calloc((rows+2) * (cols+2), sizeof(uint8_t)); } else if (imageType == RGB) { filesize = width*3 * height; bufsize = filesize / num_processes; nbytes = bufsize / sizeof(uint8_t); src = calloc((rows+2) * (cols*3+6), sizeof(uint8_t)); dst = calloc((rows+2) * (cols*3+6), sizeof(uint8_t)); } if (src == NULL || dst == NULL) { fprintf(stderr, "%s: Not enough memory\n", argv[0]); MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); return EXIT_FAILURE; } /* Parallel read */ MPI_File_open(MPI_COMM_WORLD, image, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); if (imageType == GREY) { for (i = 1 ; i <= rows ; i++) { MPI_File_seek(fh, (start_row + i-1) * width + start_col, MPI_SEEK_SET); tmpbuf = offset(src, i, 1, cols+2); MPI_File_read(fh, tmpbuf, cols, MPI_BYTE, &status); } } else if (imageType == RGB) { for (i = 1 ; i <= rows ; i++) { MPI_File_seek(fh, 3*(start_row + i-1) * width + 3*start_col, MPI_SEEK_SET); tmpbuf = offset(src, i, 3, cols*3+6); MPI_File_read(fh, tmpbuf, cols*3, MPI_BYTE, &status); } } MPI_File_close(&fh); /* Compute neighbours */ if (start_row != 0) north = process_id - col_div; if (start_row + rows != height) south = process_id + col_div; if (start_col != 0) west = process_id - 1; if (start_col + cols != width) east = process_id + 1; /* Get time before */ timer = MPI_Wtime(); /* Convolute "loops" times */ for (t = 0 ; t < loops ; t++) { /* Send and request borders */ if (imageType == GREY) { if (north != -1) { MPI_Isend(offset(src, 1, 1, cols+2), 1, grey_row_type, north, 0, MPI_COMM_WORLD, &send_north_req); MPI_Irecv(offset(src, 0, 1, cols+2), 1, grey_row_type, north, 0, MPI_COMM_WORLD, &recv_north_req); } if (west != -1) { MPI_Isend(offset(src, 1, 1, cols+2), 1, grey_col_type, west, 0, MPI_COMM_WORLD, &send_west_req); MPI_Irecv(offset(src, 1, 0, cols+2), 1, grey_col_type, west, 0, MPI_COMM_WORLD, &recv_west_req); } if (south != -1) { MPI_Isend(offset(src, rows, 1, cols+2), 1, grey_row_type, south, 0, MPI_COMM_WORLD, &send_south_req); MPI_Irecv(offset(src, rows+1, 1, cols+2), 1, grey_row_type, south, 0, MPI_COMM_WORLD, &recv_south_req); } if (east != -1) { MPI_Isend(offset(src, 1, cols, cols+2), 1, grey_col_type, east, 0, MPI_COMM_WORLD, &send_east_req); MPI_Irecv(offset(src, 1, cols+1, cols+2), 1, grey_col_type, east, 0, MPI_COMM_WORLD, &recv_east_req); } } else if (imageType == RGB) { if (north != -1) { MPI_Isend(offset(src, 1, 3, 3*cols+6), 1, rgb_row_type, north, 0, MPI_COMM_WORLD, &send_north_req); MPI_Irecv(offset(src, 0, 3, 3*cols+6), 1, rgb_row_type, north, 0, MPI_COMM_WORLD, &recv_north_req); } if (west != -1) { MPI_Isend(offset(src, 1, 3, 3*cols+6), 1, rgb_col_type, west, 0, MPI_COMM_WORLD, &send_west_req); MPI_Irecv(offset(src, 1, 0, 3*cols+6), 1, rgb_col_type, west, 0, MPI_COMM_WORLD, &recv_west_req); } if (south != -1) { MPI_Isend(offset(src, rows, 3, 3*cols+6), 1, rgb_row_type, south, 0, MPI_COMM_WORLD, &send_south_req); MPI_Irecv(offset(src, rows+1, 3, 3*cols+6), 1, rgb_row_type, south, 0, MPI_COMM_WORLD, &recv_south_req); } if (east != -1) { MPI_Isend(offset(src, 1, 3*cols, 3*cols+6), 1, rgb_col_type, east, 0, MPI_COMM_WORLD, &send_east_req); MPI_Irecv(offset(src, 1, 3*cols+3, 3*cols+6), 1, rgb_col_type, east, 0, MPI_COMM_WORLD, &recv_east_req); } } /* Inner Data Convolute */ convolute(src, dst, 1, rows, 1, cols, cols, rows, h, imageType); /* Request and compute */ if (north != -1) { MPI_Wait(&recv_north_req, &status); convolute(src, dst, 1, 1, 2, cols-1, cols, rows, h, imageType); } if (west != -1) { MPI_Wait(&recv_west_req, &status); convolute(src, dst, 2, rows-1, 1, 1, cols, rows, h, imageType); } if (south != -1) { MPI_Wait(&recv_south_req, &status); convolute(src, dst, rows, rows, 2, cols-1, cols, rows, h, imageType); } if (east != -1) { MPI_Wait(&recv_east_req, &status); convolute(src, dst, 2, rows-1, cols, cols, cols, rows, h, imageType); } /* Corner data */ if (north != -1 && west != -1) convolute(src, dst, 1, 1, 1, 1, cols, rows, h, imageType); if (west != -1 && south != -1) convolute(src, dst, rows, rows, 1, 1, cols, rows, h, imageType); if (south != -1 && east != -1) convolute(src, dst, rows, rows, cols, cols, cols, rows, h, imageType); if (east != -1 && north != -1) convolute(src, dst, 1, 1, cols, cols, cols, rows, h, imageType); /* Wait to have sent all borders */ if (north != -1) MPI_Wait(&send_north_req, &status); if (west != -1) MPI_Wait(&send_west_req, &status); if (south != -1) MPI_Wait(&send_south_req, &status); if (east != -1) MPI_Wait(&send_east_req, &status); /* swap arrays */ tmp = src; src = dst; dst = tmp; } /* Get time elapsed */ timer = MPI_Wtime() - timer; /* Parallel write */ char *outImage = malloc((strlen(image) + 9) * sizeof(char)); strcpy(outImage, "blur_"); strcat(outImage, image); MPI_File outFile; MPI_File_open(MPI_COMM_WORLD, outImage, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &outFile); if (imageType == GREY) { for (i = 1 ; i <= rows ; i++) { MPI_File_seek(outFile, (start_row + i-1) * width + start_col, MPI_SEEK_SET); tmpbuf = offset(src, i, 1, cols+2); MPI_File_write(outFile, tmpbuf, cols, MPI_BYTE, MPI_STATUS_IGNORE); } } else if (imageType == RGB) { for (i = 1 ; i <= rows ; i++) { MPI_File_seek(outFile, 3*(start_row + i-1) * width + 3*start_col, MPI_SEEK_SET); tmpbuf = offset(src, i, 3, cols*3+6); MPI_File_write(outFile, tmpbuf, cols*3, MPI_BYTE, MPI_STATUS_IGNORE); } } MPI_File_close(&outFile); /* Get times from other processes and print maximum */ if (process_id != 0) MPI_Send(&timer, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); else { for (i = 1 ; i != num_processes ; ++i) { MPI_Recv(&remote_time, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); if (remote_time > timer) timer = remote_time; } printf("%f\n", timer); } /* De-allocate space */ free(src); free(dst); MPI_Type_free(&rgb_col_type); MPI_Type_free(&rgb_row_type); MPI_Type_free(&grey_col_type); MPI_Type_free(&grey_row_type); /* Finalize and exit */ MPI_Finalize(); return EXIT_SUCCESS; }
//tests the methods used encoding and decoding, uses insert_errors2 to accomodate any bit rate float message_pass_rate(int num_tests, float BER) { int successes = 0; int errors = 0; int tries = 0; int wrong1 = 0, wrong2 = 0; //for(unsigned int i = 0; i < num_tests; i++) while(errors < 100) { raw_data rd; rd.length = 64; rd.data = (uint8_t*)alloc_named(rd.length, "message_pass_rate rd"); unsigned int i; for(i = 0; i < 64; i++) rd.data[i] = rand(); int t = 2; //PYTHON// //p = make_packet(rd); //encoded_packet ep = encode(&p); //currently convolutional- subject to change raw_data rs_encoded = rs_encode(rd, t); raw_data ep = convolute(rs_encoded); interleave(ep); //interleaves data in place insert_errors2(ep.data, ep.length, BER); deinterleave(ep); raw_data deconvoluted = deconvolute(ep, NULL); int isc = is_correctible(rs_encoded, deconvoluted, t, 0); raw_data decoded; rs_decode(deconvoluted, &decoded, t, NULL); //q = decode(ep, NULL); if(rd.length != decoded.length) { printf("lengths are not the same!\n"); printf("rd.length = %i, decoded.length = %i\n", rd.length, decoded.length); } if(!memcmp(decoded.data, rd.data, rd.length)) { if(!isc) wrong1++; //if(!isc) // is_correctible(rs_encoded, deconvoluted, t, 1); //assert(isc); successes++; } else { if(isc) wrong2++; //assert(!isc); errors++; } dealloc(ep.data); dealloc(rs_encoded.data); dealloc(deconvoluted.data); dealloc(decoded.data); dealloc(rd.data); if(tries >= num_tests) { printf("tries = %i, errors = %i\n", tries, errors); break; } tries++; } //return (float)successes / (float)num_tests; printf("wrong1 = %i\n", wrong1); printf("wrong2 = %i\n", wrong2); printf("tests = %i\n", successes + errors); return (float)successes / ((float)successes + (float)errors); }