diff --git a/CompMath1/src/main.cpp b/CompMath1/src/main.cpp index 7e114bd..e2bf63e 100644 --- a/CompMath1/src/main.cpp +++ b/CompMath1/src/main.cpp @@ -12,32 +12,84 @@ double acceleration(double t) void calc(double* trace, uint32_t traceSize, double t0, double dt, double y0, double y1, int rank, int size) { - // Sighting shot - double v0 = 0; - if (rank == 0 && size > 0) - { - trace[0] = y0; - trace[1] = y0 + dt*v0; - for (uint32_t i = 2; i < traceSize; i++) - { - trace[i] = dt*dt*acceleration(t0 + (i - 1)*dt) + 2*trace[i - 1] - trace[i - 2]; - } - } + MPI_Status status; + MPI_Bcast (&traceSize, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast (&t0, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast (&dt, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); - // The final shot - if (rank == 0 && size > 0) - { - v0 = (y1 - trace[traceSize - 1])/(dt*traceSize); - trace[0] = y0; - trace[1] = y0 + dt*v0; - for (uint32_t i = 2; i < traceSize; i++) - { - trace[i] = dt*dt*acceleration(t0 + (i - 1)*dt) + 2*trace[i - 1] - trace[i - 2]; - } - } + uint32_t mySize = traceSize / size; + if (rank == 0) { + mySize += traceSize % size; + } + double tau = dt * mySize; + + if (rank != 0) { + trace = (double *)malloc(mySize * sizeof(double)); + } + // Sighting shot + double v0 = 0, v1, myY1; + t0 += tau * rank; + if (rank != 0) { + t0 += dt * (traceSize % size); + } + trace[0] = y0; + trace[1] = y0 + dt*v0; + for (uint32_t i = 2; i < mySize; i++) { + trace[i] = dt*dt*acceleration(t0 + (i - 1)*dt) + 2*trace[i - 1] - trace[i - 2]; + } + + v1 = (trace[mySize - 1] - trace[mySize - 2]) / dt; + myY1 = trace[mySize - 1]; + + if (size == 1) { + v0 = (y1 - myY1) / tau; + } else { + double bufY, bufV; + if (rank == 0) { + MPI_Send(&myY1, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD); + MPI_Send(&v1, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD); + MPI_Recv(&bufY, 1, MPI_DOUBLE, size - 1, 0, MPI_COMM_WORLD, &status); + v0 = (y1 - bufY) / (traceSize * dt); + MPI_Bcast(&v0, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + } else { + MPI_Recv(&bufY, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &status); + MPI_Recv(&bufV, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &status); + + myY1 += bufY + bufV * (mySize - 1) * dt; + v1 += bufV; + + if (rank != size - 1) { + MPI_Send(&myY1, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + MPI_Send(&v1, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + } else { + MPI_Send(&myY1, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + } + + MPI_Bcast(&v0, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + y0 = bufY + v0 * tau * rank + v0 * dt * (traceSize % size); + v0 += bufV; + } + +} + // The final shot + trace[0] = y0; + trace[1] = y0 + dt*v0; + for (uint32_t i = 2; i < mySize; i++) { + trace[i] = dt*dt*acceleration(t0 + (i - 1)*dt) + 2*trace[i - 1] - trace[i - 2]; + } + if (rank == 0) { + mySize -= (traceSize % size); + for(int i = 1; i < size; i++) { + MPI_Recv(&trace[i * mySize + (traceSize % size)], mySize, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); + } + } else { + MPI_Send(trace, mySize, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + free(trace); + } } + int main(int argc, char** argv) { int rank = 0, size = 0, status = 0; diff --git a/CompMath2/src/main.cpp b/CompMath2/src/main.cpp index 5c4527a..3eafd87 100644 --- a/CompMath2/src/main.cpp +++ b/CompMath2/src/main.cpp @@ -7,64 +7,112 @@ void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, int size) { - if (rank == 0 && size > 0) - { - double diff = 0; - double* tmpFrame = new double[ySize * xSize]; - // Prepare tmpFrame - for (uint32_t y = 0; y < ySize; y++) - { - tmpFrame[y*xSize] = frame[y*xSize]; - tmpFrame[y*xSize + xSize - 1] = frame[y*xSize + xSize - 1]; - } - for (uint32_t x = 1; x < xSize - 1; x++) - { - tmpFrame[x] = frame[x]; - tmpFrame[(ySize - 1)*xSize + x] = frame[(ySize - 1)*xSize + x]; - } - // Calculate first iteration - for (uint32_t y = 1; y < ySize - 1; y++) - { - for (uint32_t x = 1; x < xSize - 1; x++) - { - tmpFrame[y*xSize + x] = (frame[(y + 1)*xSize + x] + frame[(y - 1)*xSize + x] +\ - frame[y*xSize + x + 1] + frame[y*xSize + x - 1])/4.0; - diff += std::abs(tmpFrame[y*xSize + x] - frame[y*xSize + x]); - } - } + MPI_Status status; + MPI_Bcast (&xSize, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast (&ySize, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast (&delta, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); - double* currFrame = tmpFrame; - double* nextFrame = frame; - uint32_t iteration = 1; - // Calculate frames - while (diff > delta) - { - diff = 0; - for (uint32_t y = 1; y < ySize - 1; y++) - { - for (uint32_t x = 1; x < xSize - 1; x++) - { - nextFrame[y*xSize + x] = (currFrame[(y + 1)*xSize + x] + currFrame[(y - 1)*xSize + x] +\ - currFrame[y*xSize + x + 1] + currFrame[y*xSize + x - 1])/4.0; - diff += std::abs(nextFrame[y*xSize + x] - currFrame[y*xSize + x]); - } - } - std::swap(currFrame, nextFrame); - iteration++; - } - // Copy result from tmp - if (iteration % 2 == 1) - { - for (uint32_t i = 0; i < xSize*ySize; i++) - { - frame[i] = tmpFrame[i]; - } - } - delete tmpFrame; - } + uint32_t mySize = ySize / size; + uint32_t yFirst = mySize * rank + ySize % size; + + if (rank == 0) { + yFirst = 1; + mySize += ySize % size - 1; + } + + if (rank == size - 1) { + mySize--; + } + + uint32_t yLast = yFirst + mySize; + + double diff = 0; + + if (mySize == 0) { + diff = 2 * delta; + } + + double* inFrame = (double *)malloc(xSize * ySize * sizeof(double)); + + if (rank > 0) { + frame = (double *)malloc(xSize * ySize * sizeof(double)); + } + + MPI_Bcast (frame, xSize * ySize, MPI_DOUBLE, 0, MPI_COMM_WORLD); + memcpy(inFrame, frame, xSize * ySize * sizeof (double)); + + for (uint32_t y = yFirst; y < yLast; y++) { + for (uint32_t x = 1; x < xSize - 1; x++) { + inFrame[y * xSize + (x)] = (frame[(y + 1) * xSize + x] + frame[(y - 1) * xSize + x] + frame[y * xSize + x + 1] + frame[y * xSize + x - 1]) / 4.0; + diff += std::abs(inFrame[y * xSize + x] - frame[y * xSize + x]); + } + } + + double* p; + + while (diff > delta) + { + p = inFrame; + inFrame = frame; + frame = p; + + diff = 0; + + if (size > 1) { + if (rank == 0) { + MPI_Send (inFrame + (yLast - 1) * xSize, xSize, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + } else { + MPI_Recv (inFrame + (yFirst - 1) * xSize, xSize, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &status); + if (rank != size - 1) { + MPI_Send (inFrame + (yLast - 1) * xSize, xSize, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD); + } + } + if (rank == size - 1) { + MPI_Send (inFrame + yFirst * xSize, xSize, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD); + } else { + MPI_Recv (inFrame + yLast * xSize, xSize, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &status); + if (rank != 0) { + MPI_Send (inFrame + yFirst * xSize, xSize, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD); + } + } + } + + + + for (uint32_t y = yFirst; y < yLast; y++) { + for (uint32_t x = 1; x < xSize - 1; x++) { + frame[y * xSize + x] = (inFrame[(y + 1) * xSize + x] + inFrame[(y - 1) * xSize + x] + inFrame[y * xSize + x + 1] + inFrame[y * xSize + x - 1]) / 4.0; + diff += std::abs(frame[y * xSize + x] - inFrame[y * xSize + x]); + } + } + + MPI_Allreduce(&diff, &diff, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + } + + if (rank == 0) { + yFirst += mySize; + mySize -= (ySize % size - 1); + for (int i = 1; i < size; i++) { + if (i == size - 1) { + mySize--; + } + MPI_Recv (frame + yFirst * xSize, mySize * xSize, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); + yFirst += mySize; + } + } else { + MPI_Send (frame + yFirst * xSize, mySize * xSize, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + } + + free (inFrame); + + if (rank > 0) { + free (frame); + } } + int main(int argc, char** argv) { int rank = 0, size = 0, status = 0; diff --git a/Loop1/src/main.cpp b/Loop1/src/main.cpp index 318f940..5380c5c 100644 --- a/Loop1/src/main.cpp +++ b/Loop1/src/main.cpp @@ -5,18 +5,49 @@ #include #include +void sum(double* res, uint32_t xSize, uint32_t ySize) { + for (uint32_t y = 0; y < ySize; y++) { + for (uint32_t x = 0; x < xSize; x++) { + res[y*xSize + x] = sin(0.00001*res[y*xSize + x]); + } + } +} + + void calc(double* arr, uint32_t ySize, uint32_t xSize, int rank, int size) { - if (rank == 0 && size > 0) - { - for (uint32_t y = 0; y < ySize; y++) - { - for (uint32_t x = 0; x < xSize; x++) - { - arr[y*xSize + x] = sin(0.00001*arr[y*xSize + x]); - } - } - } + MPI_Bcast(&ySize, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&xSize, 1, MPI_INT, 0, MPI_COMM_WORLD); + uint32_t loc_ySize = ySize / size; + if (rank < (int)ySize % size) { + loc_ySize++; + } + double* res = (double*)malloc(loc_ySize * xSize * sizeof(double)); + + if (rank == 0) { + int* displs = (int*)malloc(size * sizeof(int)); + int* sendcounts = (int*)malloc(size * sizeof(int)); + int offset = 0; + for (int i = 0; i < size; i++) { + displs[i] = offset; + sendcounts[i] = ySize / size; + if (i < (int)ySize % size) { + sendcounts[i]++; + } + sendcounts[i] *= xSize; + offset += sendcounts[i]; + } + MPI_Scatterv(arr, sendcounts, displs, MPI_DOUBLE, res, loc_ySize * xSize, MPI_DOUBLE, 0, MPI_COMM_WORLD); + sum(res, xSize, loc_ySize); + MPI_Gatherv(res, loc_ySize * xSize, MPI_DOUBLE, arr, sendcounts, displs, MPI_DOUBLE, 0, MPI_COMM_WORLD); + free(displs); + free(sendcounts); + } else { + MPI_Scatterv(NULL, NULL, NULL, 0, res, loc_ySize * xSize, MPI_DOUBLE, 0, MPI_COMM_WORLD); + sum(res, xSize, loc_ySize); + MPI_Gatherv(res, loc_ySize * xSize, MPI_DOUBLE, NULL, NULL, NULL, 0, 0, MPI_COMM_WORLD); + } + free(res); } int main(int argc, char** argv) diff --git a/Loop2/src/main.cpp b/Loop2/src/main.cpp index 51ea220..d0a91c0 100644 --- a/Loop2/src/main.cpp +++ b/Loop2/src/main.cpp @@ -5,17 +5,61 @@ #include #include +void sum(double* res, uint32_t xSize, uint32_t ySize) { + for (uint32_t y = 0; y < ySize - 1; y++) { + for (uint32_t x = 3; x < xSize; x++) { + res[y*xSize + x] = sin(0.00001*res[(y+1)*xSize + x - 3]); + } + } +} + + void calc(double* arr, uint32_t ySize, uint32_t xSize, int rank, int size) { - if (rank == 0 && size > 0) - { - for (uint32_t y = 0; y < ySize - 1; y++) - { - for (uint32_t x = 3; x < xSize; x++) - { - arr[y*xSize + x] = sin(0.00001*arr[(y + 1)*xSize + x - 3]); + MPI_Status status; + MPI_Bcast(&ySize, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&xSize, 1, MPI_INT, 0, MPI_COMM_WORLD); + uint32_t loc_ySize = ySize / size; + if (rank < (int)(ySize % size)){ + loc_ySize++; + } + if (rank == size - 1) { + loc_ySize--; + } + if (rank == 0) { + uint32_t send_ySize = loc_ySize; + uint32_t send_yAddr = loc_ySize; + for (int i = 1; i < size; i++) { + if (i == (int)(ySize % size)) { + send_ySize--; + } + if (i == size - 1) { + send_ySize--; + } + MPI_Send(&arr[send_yAddr * xSize], (send_ySize + 1) * xSize, MPI_DOUBLE, i, 0, MPI_COMM_WORLD); + send_yAddr += send_ySize; + } + } else { + arr = (double*) malloc((loc_ySize + 1) * xSize * sizeof(double)); + MPI_Recv(arr, (loc_ySize + 1) * xSize, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status); + } + sum(arr, xSize, loc_ySize + 1); + if (rank == 0) { + uint32_t recv_ySize = loc_ySize; + uint32_t recv_yAddr = loc_ySize; + for (int i = 1; i < size; i++) { + if (i == (int)(ySize % size)) { + recv_ySize--; } + if (i == size - 1) { + recv_ySize--; + } + MPI_Recv(&arr[recv_yAddr * xSize], recv_ySize * xSize, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); + recv_yAddr += recv_ySize; } + } else { + MPI_Send(arr, loc_ySize * xSize, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + free(arr); } } diff --git a/Loop3/src/main.cpp b/Loop3/src/main.cpp index 43cce1f..abc7abf 100644 --- a/Loop3/src/main.cpp +++ b/Loop3/src/main.cpp @@ -5,18 +5,61 @@ #include #include +void sum(double* arr, uint32_t xSize, uint32_t ySize) { + for (uint32_t x = 0; x < xSize; x++) { + for (uint32_t y = 4; y < ySize; y++) { + arr[x*ySize + y] = sin(arr[x*ySize + (y-4)]); + } + } +} + void calc(double* arr, uint32_t ySize, uint32_t xSize, int rank, int size) { - if (rank == 0 && size > 0) - { - for (uint32_t y = 4; y < ySize; y++) - { - for (uint32_t x = 0; x < xSize; x++) - { - arr[y*xSize + x] = sin(arr[(y - 4)*xSize + x]); - } - } - } + MPI_Bcast(&ySize, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&xSize, 1, MPI_INT, 0, MPI_COMM_WORLD); + uint32_t loc_xSize = xSize / size; + if (rank < (int)xSize % size) { + loc_xSize++; + } + double* res = (double*)malloc(loc_xSize * ySize * sizeof(double)); + + if (rank == 0) { + double* arr_T = (double *)malloc(ySize * xSize * sizeof(double)); + for(int i = 0; i < (int)ySize; i++) { + for(int j = 0; j < (int)xSize; j++) { + arr_T[j*ySize + i] = arr[i*xSize + j]; + } + } + + int* displs = (int*)malloc(size * sizeof(int)); + int* sendcounts = (int*)malloc(size * sizeof(int)); + int offset = 0; + for (int i = 0; i < size; i++) { + displs[i] = offset; + sendcounts[i] = xSize / size; + if (i < (int)xSize % size) { + sendcounts[i]++; + } + sendcounts[i] *= ySize; + offset += sendcounts[i]; + } + MPI_Scatterv(arr_T, sendcounts, displs, MPI_DOUBLE, res, loc_xSize * ySize, MPI_DOUBLE, 0, MPI_COMM_WORLD); + sum(res, loc_xSize, ySize); + MPI_Gatherv(res, loc_xSize * ySize, MPI_DOUBLE, arr_T, sendcounts, displs, MPI_DOUBLE, 0, MPI_COMM_WORLD); + for(int i = 0; i < (int)xSize; i++) { + for(int j = 0; j < (int)ySize; j++) { + arr[j*xSize + i] = arr_T[i*ySize + j]; + } + } + free(displs); + free(sendcounts); + free(arr_T); + } else { + MPI_Scatterv(NULL, NULL, NULL, 0, res, loc_xSize * ySize, MPI_DOUBLE, 0, MPI_COMM_WORLD); + sum(res, loc_xSize, ySize); + MPI_Gatherv(res, loc_xSize * ySize, MPI_DOUBLE, NULL, NULL, NULL, 0, 0, MPI_COMM_WORLD); + } + free(res); } int main(int argc, char** argv) diff --git a/Loop4/src/main.cpp b/Loop4/src/main.cpp index d958d54..3185580 100644 --- a/Loop4/src/main.cpp +++ b/Loop4/src/main.cpp @@ -7,14 +7,113 @@ void calc(double* arr, uint32_t zSize, uint32_t ySize, uint32_t xSize, int rank, int size) { - if (rank == 0 && size > 0) { - for (uint32_t z = 1; z < zSize; z++) { - for (uint32_t y = 0; y < ySize - 1; y++) { - for (uint32_t x = 0; x < xSize - 1; x++) { - arr[z*ySize*xSize + y*xSize + x] = sin(arr[(z - 1)*ySize*xSize + (y + 1)*xSize + x + 1]); + MPI_Status status; + + uint32_t num_of_tasks, arr_size = 0, arr_addr = 0; + + if (rank == 0) { + double* new_arr = (double *) malloc(zSize * ySize * xSize * sizeof(double)); + bool* added = (bool *) calloc(zSize * ySize * xSize, sizeof(bool)); + int z, y, x; + uint32_t* tasks = (uint32_t*) malloc(zSize * ySize * xSize * sizeof(uint32_t)); + uint32_t counter = 0, task_counter = 0, local_counter = 0, send_num_of_tasks, send_task_addr, send_arr_size[size], send_arr_addr; + for (int i = 0; i < (int)zSize; i++) { + for (int j = 0; j < (int)ySize; j++) { + for (int k = 0; k < (int)xSize; k++) { + if (added[i * ySize * xSize + j * xSize + k] == false) { + z = i; + y = j; + x = k; + local_counter = 0; + while (z < (int)zSize && y >= 0 && x >= 0) { + added[z * ySize * xSize + y * xSize + x] = true; + new_arr[counter] = arr[z * ySize * xSize + y * xSize + x]; + counter++; + local_counter++; + z++; + y--; + x--; + } + tasks[task_counter] = local_counter; + task_counter++; + } + } + } + } + num_of_tasks = task_counter / size; + if (task_counter % size > 0) { + num_of_tasks++; + } + send_arr_addr = 0; + for (int i = 0; i < (int)num_of_tasks; i++) { + arr_size += tasks[i]; + } + send_arr_addr = arr_size; + send_num_of_tasks = num_of_tasks; + send_task_addr = num_of_tasks; + for (int i = 1; i < size; i++) { + send_arr_size[i] = 0; + if (i == (int)task_counter % size) { + send_num_of_tasks--; + } + for (int j = 0; j < (int)send_num_of_tasks; j++) { + send_arr_size[i] += tasks[send_task_addr + j]; + } + MPI_Send(&send_num_of_tasks, 1, MPI_INT, i, 0, MPI_COMM_WORLD); + MPI_Send(&send_arr_size[i], 1, MPI_INT, i, 0, MPI_COMM_WORLD); + MPI_Send(&tasks[send_task_addr], send_num_of_tasks, MPI_INT, i, 0, MPI_COMM_WORLD); + MPI_Send(&new_arr[send_arr_addr], send_arr_size[i], MPI_DOUBLE, i, 0, MPI_COMM_WORLD); + send_arr_addr += send_arr_size[i]; + send_task_addr += send_num_of_tasks; + } + for (int i = 0; i < (int)num_of_tasks; i++) { + for (int j = 0; j < (int)(tasks[i] - 1); j++) { + new_arr[j + arr_addr + 1] = sin(new_arr[j + arr_addr]); + } + arr_addr += tasks[i]; + } + send_arr_addr = arr_size; + for (int i = 1; i < size; i++) { + MPI_Recv(&new_arr[send_arr_addr], send_arr_size[i], MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); + send_arr_addr += send_arr_size[i]; + } + counter = 0; + for (int i = 0; i < (int)zSize; i++) { + for (int j = 0; j < (int)ySize; j++) { + for (int k = 0; k < (int)xSize; k++) { + if (added[i * ySize * xSize + j * xSize + k] == true) { + z = i; + y = j; + x = k; + while (z < (int)zSize && y >= 0 && x >= 0) { + added[z * ySize * xSize + y * xSize + x] = false; + arr[z * ySize * xSize + y * xSize + x] = new_arr[counter]; + counter++; + z++; + y--; + x--; + } + } } } } + free(added); + free(new_arr); + } else { + MPI_Recv(&num_of_tasks, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); + MPI_Recv(&arr_size, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); + uint32_t* tasks = (uint32_t *) malloc(num_of_tasks * sizeof(uint32_t)); + arr = (double *) malloc(arr_size * sizeof(double)); + MPI_Recv(tasks, num_of_tasks, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); + MPI_Recv(arr, arr_size, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status); + for (int i = 0; i < (int)num_of_tasks; i++) { + for (int j = 0; j < (int)(tasks[i] - 1); j++) { + arr[j + arr_addr + 1] = sin(arr[j + arr_addr]); + } + arr_addr += tasks[i]; + } + MPI_Send(arr, arr_size, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); + free(arr); } } diff --git a/OpenMP2/src/main.cpp b/OpenMP2/src/main.cpp index 8dab215..61f2dcd 100644 --- a/OpenMP2/src/main.cpp +++ b/OpenMP2/src/main.cpp @@ -2,10 +2,22 @@ #include #include #include +#include double calc(uint32_t x_last, uint32_t num_threads) { - return 0; + double res = 0; + double* a = (double*)malloc(x_last * sizeof(double));; + + #pragma omp parallel for num_threads(num_threads) + for (uint32_t i = 0; i < x_last; i++) { + a[i] = 1.0 / (i + 1); + } + for (uint32_t i = x_last; i > 0; i--) { + res += a[i - 1]; + } + free(a); + return res; } int main(int argc, char** argv) diff --git a/OpenMP3/src/main.cpp b/OpenMP3/src/main.cpp index 416ee06..2ae7077 100644 --- a/OpenMP3/src/main.cpp +++ b/OpenMP3/src/main.cpp @@ -9,9 +9,36 @@ double func(double x) return sin(x); } +double trapezoid(double x0, double x1, double dx) { + return dx * (func(x0) + func(x1)) * 0.5; +} + double calc(double x0, double x1, double dx, uint32_t num_threads) { - return 0; + int num_of_dots = (x1 - x0) / dx + 1; + double* dots = (double*)malloc(num_of_dots * sizeof(double)); + double res = 0.0; + double trap = 0.0; + double c = 0.0; + double y = 0.0; + double t = 0.0; + #pragma omp parallel num_threads(num_threads) + { + #pragma omp for + for (int i = 0; i < num_of_dots; i++) { + dots[i] = x0 + i * dx; + } + #pragma omp for reduction(+:res) private(y, t, c, trap) + for (int i = 0; i < num_of_dots - 1; i++) { + trap = trapezoid(dots[i], dots[i+1], dx); + y = trap - c; + t = res + y; + c = (t - res) - y; + res = t; + } + } + free(dots); + return res; } int main(int argc, char** argv) diff --git a/OpenMP4/src/main.cpp b/OpenMP4/src/main.cpp index 036d8e3..0a5e133 100644 --- a/OpenMP4/src/main.cpp +++ b/OpenMP4/src/main.cpp @@ -5,7 +5,32 @@ double calc(uint32_t x_last, uint32_t num_threads) { - return 0; + double* loc_res = (double*)calloc(num_threads, sizeof(double)); + double* loc_fact = (double*)malloc(num_threads * sizeof(double)); + + #pragma omp parallel num_threads(num_threads) + { + int tid = omp_get_thread_num(); + loc_fact[tid] = 1.0; + + #pragma omp for + for (uint32_t i = 1; i < x_last; i++) { + loc_fact[tid] /= double(i); + loc_res[tid] += loc_fact[tid]; + } + } + + double res = 1.0; + double fact = 1.0; + + for (uint32_t tid = 0; tid < num_threads; tid++) { + res += loc_res[tid] * fact; + fact *= loc_fact[tid]; + } + + free(loc_fact); + free(loc_res); + return res; } int main(int argc, char** argv) diff --git a/OpenMP5/src/main.cpp b/OpenMP5/src/main.cpp index bf042c5..b24b04e 100644 --- a/OpenMP5/src/main.cpp +++ b/OpenMP5/src/main.cpp @@ -5,7 +5,91 @@ void calc(uint32_t xSize, uint32_t ySize, uint32_t iterations, uint32_t num_threads, uint8_t* inputFrame, uint8_t* outputFrame) { + int* inFrame = (int*)malloc(xSize*ySize * sizeof(int)); + int* outFrame = (int *)malloc(xSize*ySize * sizeof(int)); + for (uint32_t y = 0; y < ySize; y++) { + for (uint32_t x = 0; x < xSize; x++) { + outFrame[y * xSize + x] = (int)inputFrame[y * xSize + x]; + } + } + uint32_t block_size = xSize / num_threads; + uint32_t block_extra = xSize % num_threads; + #pragma omp parallel num_threads(num_threads) + { + uint32_t tid = omp_get_thread_num(); + + uint32_t first = tid * block_size; + uint32_t last = (tid + 1) * block_size; + + if (tid == num_threads - 1) { + last += block_extra; + } + + + for (uint32_t i = 0; i < iterations; i++) { + #pragma omp barrier + #pragma omp single + { + int* ptr = inFrame; + inFrame = outFrame; + outFrame = ptr; + } + for (uint32_t x = first; x < last; x++) { + for (uint32_t y = 0; y < ySize; y++) { + uint32_t count = 0; + + uint32_t x1 = x == 0 ? xSize - 1 : x - 1; + uint32_t x2 = x == xSize - 1 ? 0 : x + 1; + uint32_t y1 = y == 0 ? ySize - 1 : y - 1; + uint32_t y2 = y == ySize - 1 ? 0 : y + 1; + + + if (inFrame[y1 * xSize + x] == 1){ + count++; + } + if (inFrame[y1 * xSize + x1] == 1) { + count++; + } + if (inFrame[y1 * xSize + x2] == 1) { + count++; + } + if (inFrame[y2 * xSize + x1] == 1) { + count++; + } + if (inFrame[y2 * xSize + x2] == 1) { + count++; + } + + if (inFrame[y2 * xSize + x] == 1) { + count++; + } + if (inFrame[y * xSize + x1] == 1) { + count++; + } + if (inFrame[y * xSize + x2] == 1) { + count++; + } + + if (inFrame[y * xSize + x] == 0 && count == 3) { + outFrame[y * xSize + x] = 1; + } else if (inFrame[y * xSize + x] == 1 && (count < 2 || count > 3)) { + outFrame[y * xSize + x] = 0; + } else { + outFrame[y * xSize + x] = inFrame[y * xSize + x]; + } + } + } + } + } + + for (uint32_t y = 0; y < ySize; y++) { + for (uint32_t x = 0; x < xSize; x++) { + outputFrame[y * xSize + x] = outFrame[y * xSize + x]; + } + } + free(inFrame); + free(outFrame); } int main(int argc, char** argv) @@ -63,8 +147,8 @@ int main(int argc, char** argv) } // Prepare to exit - delete outputFrame; - delete inputFrame; + delete[] outputFrame; + delete[] inputFrame; output.close(); input.close(); return 0; diff --git a/heatmap/heatmap.c b/heatmap/heatmap.c new file mode 100644 index 0000000..916f90d --- /dev/null +++ b/heatmap/heatmap.c @@ -0,0 +1,50 @@ +#include +#include + +int create_thread(int n) +{ + int res = 0; + #pragma omp parallel num_threads(n) + { + res++; + } + return res; +} + +int main() +{ + FILE * fp; + fp = fopen("heatmap.csv","w"); + for (int x = 0; x <= 30; x++) { + if (x != 30) { + fprintf(fp, "%d,", x); + } else { + fprintf(fp, "%d\n", x); + } + } + + omp_set_nested(1); + for (int y = 1; y <= 30; y++) { + fprintf(fp, "%d,", y); + for (int x = 1; x <= 30; x++) { + double start = omp_get_wtime(); + int res = 0; + #pragma omp parallel for num_threads(x) + for (int i = 0; i < 1000; i++) { + res += create_thread(y); + } + double end = omp_get_wtime(); + if (x != 30) { + fprintf(fp, "%lf,", end - start); + } else { + fprintf(fp, "%lf\n", end - start); + } + } + } + + int res = 0; + + + + return 0; +} \ No newline at end of file diff --git a/heatmap/heatmap.xlsx b/heatmap/heatmap.xlsx new file mode 100644 index 0000000..e83a72d Binary files /dev/null and b/heatmap/heatmap.xlsx differ