|
13 | 13 |
|
14 | 14 | namespace nesterov_a_test_task { |
15 | 15 |
|
16 | | -void MatMul(const InType &in_vec, int rc_size, OutType &out_vec) { |
17 | | - for (int i = 0; i < rc_size; ++i) { |
18 | | - for (int j = 0; j < rc_size; ++j) { |
19 | | - out_vec[(i * rc_size) + j] = 0; |
20 | | - for (int k = 0; k < rc_size; ++k) { |
21 | | - out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; |
22 | | - } |
23 | | - } |
24 | | - } |
25 | | -} |
26 | | - |
27 | | -void MatMulTBB(const InType &in_vec, int rc_size, OutType &out_vec) { |
28 | | - tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); |
29 | | - MatMul(in_vec, rc_size, out_vec); |
30 | | -} |
31 | | - |
32 | 16 | NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { |
33 | 17 | SetTypeOfTask(GetStaticTypeOfTask()); |
34 | 18 | GetInput() = in; |
| 19 | + GetOutput() = 0; |
35 | 20 | } |
36 | 21 |
|
37 | | -bool NesterovATestTaskALL::ValidationImpl() { |
38 | | - auto sqrt_size = static_cast<int>(std::sqrt(GetInput().size())); |
39 | | - return sqrt_size * sqrt_size == static_cast<int>(GetInput().size()); |
40 | | -} |
| 22 | +bool NesterovATestTaskALL::ValidationImpl() { return (GetInput() > 0) && (GetOutput() == 0); } |
41 | 23 |
|
42 | 24 | bool NesterovATestTaskALL::PreProcessingImpl() { |
43 | | - // Init value for input and output |
44 | | - rc_size_ = static_cast<int>(std::sqrt(GetInput().size())); |
45 | | - GetOutput() = OutType(GetInput().size(), 0); |
46 | | - return true; |
| 25 | + GetOutput() = 2 * GetInput(); |
| 26 | + return GetOutput() > 0; |
47 | 27 | } |
48 | 28 |
|
49 | 29 | bool NesterovATestTaskALL::RunImpl() { |
| 30 | + for (InType i = 0; i < GetInput(); i++) { |
| 31 | + for (InType j = 0; j < GetInput(); j++) { |
| 32 | + for (InType k = 0; k < GetInput(); k++) { |
| 33 | + std::vector<InType> tmp(i + j + k, 1); |
| 34 | + GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); |
| 35 | + GetOutput() -= i + j + k; |
| 36 | + } |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + const int num_threads = ppc::util::GetNumThreads(); |
| 41 | + GetOutput() *= num_threads; |
| 42 | + |
50 | 43 | int rank = -1; |
51 | 44 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
52 | 45 | if (rank == 0) { |
| 46 | + std::atomic<int> counter(0); |
53 | 47 | #pragma omp parallel default(none) |
54 | 48 | { |
55 | | -#pragma omp critical |
56 | | - MatMul(GetInput(), rc_size_, GetOutput()); |
| 49 | + counter++; |
57 | 50 | } |
| 51 | + GetOutput() /= counter; |
58 | 52 | } else { |
59 | | - MatMulTBB(GetInput(), rc_size_, GetOutput()); |
| 53 | + GetOutput() /= num_threads; |
60 | 54 | } |
61 | 55 |
|
62 | | - const int num_threads = ppc::util::GetNumThreads(); |
| 56 | + GetOutput() *= num_threads; |
63 | 57 | std::vector<std::thread> threads(num_threads); |
| 58 | + std::atomic<int> counter(0); |
64 | 59 | for (int i = 0; i < num_threads; i++) { |
65 | | - threads[i] = std::thread(MatMul, std::cref(GetInput()), rc_size_, std::ref(GetOutput())); |
| 60 | + threads[i] = std::thread([&]() { counter++; }); |
66 | 61 | threads[i].join(); |
67 | 62 | } |
| 63 | + GetOutput() /= counter; |
| 64 | + |
| 65 | + tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { counter--; }); |
| 66 | + GetOutput() += counter; |
68 | 67 |
|
69 | 68 | MPI_Barrier(MPI_COMM_WORLD); |
70 | | - return true; |
| 69 | + return GetOutput() > 0; |
71 | 70 | } |
72 | 71 |
|
73 | | -bool NesterovATestTaskALL::PostProcessingImpl() { return true; } |
| 72 | +bool NesterovATestTaskALL::PostProcessingImpl() { |
| 73 | + GetOutput() -= GetInput(); |
| 74 | + return GetOutput() > 0; |
| 75 | +} |
74 | 76 |
|
75 | 77 | } // namespace nesterov_a_test_task |
0 commit comments