Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added act
Binary file not shown.
Binary file added act.tar.gz
Binary file not shown.
Binary file added bin/act
Binary file not shown.
61 changes: 61 additions & 0 deletions check_ci_fixed.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash

echo "🔍 CI Check with System Tools"
echo "=============================="

# Используем системные инструменты
CLANG_FORMAT="/usr/bin/clang-format"
CLANG_TIDY="/usr/bin/clang-tidy"

# 1. Проверка форматирования
echo "1. Checking code formatting..."
if [ -f "$CLANG_FORMAT" ]; then
find tasks/sizov_d_string_mismatch_count -name "*.cpp" -o -name "*.hpp" | \
xargs $CLANG_FORMAT --dry-run --Werror
if [ $? -eq 0 ]; then
echo "✅ Formatting: OK"
else
echo "❌ Formatting: Issues found"
exit 1
fi
else
echo "⚠️ clang-format not found, skipping formatting check"
fi

# 2. Проверка clang-tidy
echo "2. Running clang-tidy..."
mkdir -p build
cd build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. > /dev/null 2>&1
cd ..

FAILED=0
for file in $(find tasks/sizov_d_string_mismatch_count -name "*.cpp" -o -name "*.hpp"); do
echo " $file"
$CLANG_TIDY -p build "$file" 2>&1 | grep -q "error:" && {
echo " ❌ Errors found"
$CLANG_TIDY -p build "$file" 2>&1 | grep "error:" | head -2
FAILED=1
} || echo " ✅ OK"
done

if [ $FAILED -eq 0 ]; then
echo "✅ Clang-tidy: All files passed"
else
echo "❌ Clang-tidy: Some files failed"
exit 1
fi

# 3. Проверка сборки
echo "3. Checking build..."
cd build
if make -j4 > /dev/null 2>&1; then
echo "✅ Build: Successful"
else
echo "❌ Build: Failed"
exit 1
fi
cd ..

echo "=============================="
echo "🎉 All checks passed!"
79 changes: 79 additions & 0 deletions local_ci_check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash

set -e

echo "🚀 Starting Local CI Simulation"
echo "================================="

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# Function to print status
print_status() {
if [ $1 -eq 0 ]; then
echo -e "${GREEN}✓ $2${NC}"
else
echo -e "${RED}✗ $2${NC}"
exit 1
fi
}

# 1. Check .clang-format syntax
echo "1. Validating .clang-format configuration..."
clang-format -style=file -dump-config > /dev/null
print_status $? ".clang-format syntax"

# 2. Code formatting check
echo "2. Checking code formatting..."
find tasks/sizov_d_string_mismatch_count -name "*.cpp" -o -name "*.hpp" | \
xargs clang-format --dry-run --Werror --ferror-limit=0
print_status $? "Code formatting"

# 3. Ensure build directory exists
echo "3. Setting up build environment..."
mkdir -p build
cd build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. > /dev/null 2>&1
cd ..
print_status $? "Build setup"

# 4. Clang-tidy analysis
echo "4. Running clang-tidy analysis..."
FAILED_FILES=0
for file in $(find tasks/sizov_d_string_mismatch_count -name "*.cpp" -o -name "*.hpp"); do
echo " Analyzing: $file"
if clang-tidy -p build "$file" --format-style=file 2>&1 | grep -q "error:\|warning:"; then
echo -e " ${RED}✗ Issues found${NC}"
clang-tidy -p build "$file" --format-style=file 2>&1 | grep "error:\|warning:" | head -3
FAILED_FILES=$((FAILED_FILES + 1))
else
echo -e " ${GREEN}✓ OK${NC}"
fi
done

if [ $FAILED_FILES -eq 0 ]; then
echo -e "${GREEN}✓ All files passed clang-tidy${NC}"
else
echo -e "${RED}✗ $FAILED_FILES files have clang-tidy issues${NC}"
exit 1
fi

# 5. Build verification
echo "5. Verifying build..."
cd build
if make -j4 > build.log 2>&1; then
echo -e "${GREEN}✓ Build successful${NC}"
else
echo -e "${RED}✗ Build failed${NC}"
echo "Build log:"
tail -20 build.log
exit 1
fi
cd ..

echo "================================="
echo -e "${GREEN}🎉 All CI checks passed!${NC}"
echo "You can safely push to your branch"
15 changes: 15 additions & 0 deletions tasks/sizov_d_string_mismatch_count/common/include/common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <string>
#include <tuple>

#include "task/include/task.hpp"

namespace sizov_d_string_mismatch_count {

using InType = std::tuple<std::string, std::string>;
using OutType = int;
using TestType = std::string;
using BaseTask = ppc::task::Task<InType, OutType>;

} // namespace sizov_d_string_mismatch_count
2 changes: 2 additions & 0 deletions tasks/sizov_d_string_mismatch_count/data/strings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1234567890
12345X7890
9 changes: 9 additions & 0 deletions tasks/sizov_d_string_mismatch_count/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"student": {
"first_name": "Дмитрий",
"last_name": "Сизов",
"middle_name": "Игоревич",
"group_number": "3823Б1ФИ2",
"task_number": "1"
}
}
29 changes: 29 additions & 0 deletions tasks/sizov_d_string_mismatch_count/mpi/include/ops_mpi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <string>

#include "sizov_d_string_mismatch_count/common/include/common.hpp"
#include "task/include/task.hpp"

namespace sizov_d_string_mismatch_count {

class SizovDStringMismatchCountMPI : public BaseTask {
public:
static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() {
return ppc::task::TypeOfTask::kMPI;
}

explicit SizovDStringMismatchCountMPI(const InType &input);

private:
std::string str_a_;
std::string str_b_;
int global_result_ = 0;

bool ValidationImpl() override;
bool PreProcessingImpl() override;
bool RunImpl() override;
bool PostProcessingImpl() override;
};

} // namespace sizov_d_string_mismatch_count
68 changes: 68 additions & 0 deletions tasks/sizov_d_string_mismatch_count/mpi/src/ops_mpi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "sizov_d_string_mismatch_count/mpi/include/ops_mpi.hpp"

#include <mpi.h>

#include <algorithm>
#include <string>
#include <string_view>

#include "sizov_d_string_mismatch_count/common/include/common.hpp"

namespace sizov_d_string_mismatch_count {
SizovDStringMismatchCountMPI::SizovDStringMismatchCountMPI(const InType &input) {
SetTypeOfTask(GetStaticTypeOfTask());
GetInput() = input;
GetOutput() = 0;
}

bool SizovDStringMismatchCountMPI::ValidationImpl() {
const auto &input = GetInput();
const auto &a = std::get<0>(input);
const auto &b = std::get<1>(input);
return !a.empty() && a.size() == b.size();
}

bool SizovDStringMismatchCountMPI::PreProcessingImpl() {
const auto &input = GetInput();
str_a_ = std::get<0>(input);
str_b_ = std::get<1>(input);
return true;
}

bool SizovDStringMismatchCountMPI::RunImpl() {
int rank = 0;
int size = 0;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

const int total_size = static_cast<int>(str_a_.size());
if (total_size == 0) {
return true;
}

const int base = total_size / size;
const int remainder = total_size % size;
const int start = (rank * base) + std::min(rank, remainder);
const int local_size = base + (rank < remainder ? 1 : 0);

std::string_view local_a(str_a_.data() + start, local_size);
std::string_view local_b(str_b_.data() + start, local_size);

int local_result = 0;
for (int i = 0; i < local_size; ++i) {
if (local_a[i] != local_b[i]) {
++local_result;
}
}

MPI_Reduce(&local_result, &global_result_, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Bcast(&global_result_, 1, MPI_INT, 0, MPI_COMM_WORLD);

GetOutput() = global_result_;
return true;
}

bool SizovDStringMismatchCountMPI::PostProcessingImpl() {
return true;
}
} // namespace sizov_d_string_mismatch_count
44 changes: 44 additions & 0 deletions tasks/sizov_d_string_mismatch_count/report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
### Отчёт по задаче: "Подсчет числа несовпадающих символов двух строк"
**Вариант:** №27
**Выполнил студент группы 3823Б1ФИ2:** Сизов Дмитрий Игоревич
**Работу проверили:** преподаватель Нестеров Александр Юрьевич и преподаватель Оболенский Арсений Андреевич

## Введение
В рамках данной работы реализован алгоритм подсчета несовпадающих символов в двух строках одинаковой длины, а также выполнена его параллелизация с использованием технологии MPI. Целью является ускорение вычислений за счет распределения работы между несколькими процессами.

## Постановка задачи и формальное описание
Имеются две строки одинаковой длины. Требуется определить количество позиций, на которых символы в строках различаются.
Формально: пусть `A` и `B` — строки длины `n`. Необходимо вычислить:
`count = количество таких i, что A[i] ≠ B[i] для 0 ≤ i < n`

## Пример
Строка A: `"abcde"`
Строка B: `"abzdf"`
Несовпадения: 2 (позиции 2 и 4)

## Реализация разделена на модули
- `ops_seq.hpp` и `ops_seq.cpp` — реализация последовательного алгоритма
- `ops_mpi.hpp` и `ops_mpi.cpp` — реализация параллельного алгоритма
- `common.hpp` — общее определение входных/выходных типов

## Описание последовательной версии
Алгоритм проходит по всем символам строк и сравнивает их попарно. Каждое несовпадение увеличивает счетчик. Итог — общее количество отличий.

## Описание параллельной версии
Параллельный алгоритм с использованием MPI делит входные строки на блоки, равномерно распределяемые между процессами. Каждый процесс сравнивает символы в своем участке и подсчитывает количество несовпадений. Частичные результаты объединяются с помощью `MPI_Reduce`, а итоговая сумма сохраняется на процессе с рангом 0.
Такой подход позволяет ускорить вычисления за счёт распределённой обработки данных.

## Тестирования разделены на модули
- `functional/main.cpp` — функциональные тесты
- `performance/main.cpp` — производительные тесты

## Функциональное тестирование
Функциональные тесты предназначены для проверки корректности работы алгоритма на заранее известных входных данных.
В рамках теста используются строки, считываемые из файла `strings.txt`. Файл содержит две строки, которые сравниваются с помощью обеих реализаций.
Ожидаемый результат рассчитывается в рамках теста: для каждой позиции двух строк выполняется сравнение, и при обнаружении различий счётчик увеличивается.
Результат, возвращаемый алгоритмом, сопоставляется с ожидаемым значением. Это позволяет удостовериться в корректности как последовательной, так и MPI-реализации.

## Тестирование производительности
В тестировании на производительность формируются две строки по 1 миллиону символов.
Первая строка полностью состоит из символов `'a'`, вторая — копия первой, но с заменой первых 10% символов на `'b'`.
Это гарантирует строго определённое число несовпадений (100 000), что позволяет точно проверить корректность результата.
29 changes: 29 additions & 0 deletions tasks/sizov_d_string_mismatch_count/seq/include/ops_seq.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <string>

#include "sizov_d_string_mismatch_count/common/include/common.hpp"
#include "task/include/task.hpp"

namespace sizov_d_string_mismatch_count {

class SizovDStringMismatchCountSEQ : public BaseTask {
public:
static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() {
return ppc::task::TypeOfTask::kSEQ;
}

explicit SizovDStringMismatchCountSEQ(const InType &input);

private:
std::string str_a_;
std::string str_b_;
int result_ = 0;

bool ValidationImpl() override;
bool PreProcessingImpl() override;
bool RunImpl() override;
bool PostProcessingImpl() override;
};

} // namespace sizov_d_string_mismatch_count
46 changes: 46 additions & 0 deletions tasks/sizov_d_string_mismatch_count/seq/src/ops_seq.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "sizov_d_string_mismatch_count/seq/include/ops_seq.hpp"

#include <cstddef>
#include <string>

#include "sizov_d_string_mismatch_count/common/include/common.hpp"

namespace sizov_d_string_mismatch_count {

SizovDStringMismatchCountSEQ::SizovDStringMismatchCountSEQ(const InType &input) {
SetTypeOfTask(GetStaticTypeOfTask());
GetInput() = input;
GetOutput() = 0;
}

bool SizovDStringMismatchCountSEQ::ValidationImpl() {
const auto &input = GetInput();
const auto &a = std::get<0>(input);
const auto &b = std::get<1>(input);
return !a.empty() && a.size() == b.size();
}

bool SizovDStringMismatchCountSEQ::PreProcessingImpl() {
const auto &input = GetInput();
str_a_ = std::get<0>(input);
str_b_ = std::get<1>(input);
result_ = 0;
return true;
}

bool SizovDStringMismatchCountSEQ::RunImpl() {
result_ = 0;
for (std::size_t i = 0; i < str_a_.size(); ++i) {
if (str_a_[i] != str_b_[i]) {
++result_;
}
}
return true;
}

bool SizovDStringMismatchCountSEQ::PostProcessingImpl() {
GetOutput() = result_;
return true;
}

} // namespace sizov_d_string_mismatch_count
Loading
Loading