{"id":21879522,"url":"https://github.com/nerooc/upc-cannon-algorithm","last_synced_at":"2025-07-15T05:35:34.746Z","repository":{"id":124517201,"uuid":"498395097","full_name":"nerooc/upc-cannon-algorithm","owner":"nerooc","description":"Cannon's algorithm implemented in C with UPC (PGAS)","archived":false,"fork":false,"pushed_at":"2022-06-14T13:50:10.000Z","size":72,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-22T00:17:02.328Z","etag":null,"topics":["cannon","matrix-multiplication-parallel","upc"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nerooc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-31T15:34:05.000Z","updated_at":"2022-06-14T15:28:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"a28d943e-95a1-4b7a-9836-46ab01f52012","html_url":"https://github.com/nerooc/upc-cannon-algorithm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nerooc/upc-cannon-algorithm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fupc-cannon-algorithm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fupc-cannon-algorithm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fupc-cannon-algorithm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fupc-cannon-algorithm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nerooc","download_url":"https://codeload.github.com/nerooc/upc-cannon-algorithm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fupc-cannon-algorithm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265410216,"owners_count":23760402,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cannon","matrix-multiplication-parallel","upc"],"created_at":"2024-11-28T08:17:01.815Z","updated_at":"2025-07-15T05:35:34.712Z","avatar_url":"https://github.com/nerooc.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"Gabriel Chęć, Tomasz Gajda\n# Mnożenie macierzy\n### Algorytm Cannon'a - Projekt 2 (UPC)\n\n## 1. Wstęp teoretyczny\nAlgorytm Cannon’a jest rozproszonym algorytmem mnożenia macierzy dla siatek dwuwymiarowych, który po raz pierwszy opisany został w 1969 r. przez Lynn’a Elliot’a Cannon’a.\n\n- Algorytm jest efektywny jedynie dla struktury kwadratowej,\n- Działających w algorytmie procesorów jest tyle jaki jest rozmiar macierzy.\n\n### Algorytm Cannon’a:\n\n1. Oznaczamy mnożone macierze jako A i B, macierz wynikową jako C, macierz procesów jako P.\n2. Proces P(i, j) początkowo przechowuje A(i, j), a B(i, j) oblicza blok C(i, j) macierzy wynikowej.\n3. Przekształcamy A i B w taki sposób, aby każdy proces mógł niezależnie rozpocząć mnożenie swoich lokalnych podmacierzy. \n4. Przesuwamy wszystkie podmacierze A(i, j) w lewo o i kroków i wszystkich podmacierzy B(i, j) w górę o j kroków.\n5. Wykonujemy mnożenie bloków lokalnych.\n6. Każdy blok A przesuwamy o jeden krok w lewo, a każdy blok B przesuwamy o jeden krok w górę.\n7. Wykonujemy mnożenie kolejnych bloków, dodajemy do wyniku częściowego i powtarzamy to, aż wszystkie bloki zostaną pomnożone.\n\n### Przykład obliczania jednego z elementów macierzy wynikowej\n\u003cimg width=\"731\" alt=\"Screenshot 2022-05-10 at 12 50 43\" src=\"https://user-images.githubusercontent.com/31045802/167612439-32d8979b-89a7-4d0d-9857-b9f89e1cd791.png\"\u003e\n\n## 2. Implementacja\nProgram został napisany w języku C z wykorzystaniem technologii PGAS UPC. \n\nW programie możemy znaleźć 4 funkcje:\n\n- **main** - główna funkcja zajmująca się przebiegiem algorytmu, czyli obliczeniami i przekształceniami,\n- **print_matrix** - funkcja wypisująca macierz do konsoli w sposób sformatowany,\n- **initialize_matrix** - funkcja inicjalizująca macierz poprzez wczytanie jej z pliku .csv i zapisanie w postaci tablicy,\n- **save_matrix** - funkcja zapisująca macierz w postaci pliku .csv,\n\nProgram obsługuje flagę **-v (verbose)**. Po uruchomieniu programu z tą flagą możemy zobaczyć wypisane w sposób macierze mnożone oraz macierz wynikową.\n\nRozpoczynamy od załączenia używanej przez nas biblioteki za pomocą dyrektywy **#include “upc.h”**. Potem, alokujemy obiekty globalne które będą współdzielone pomiędzy procesorami. Korzystamy w tym miejscu ze słowa kluczowego **shared**. Trzy obiekty **(A, B i C)** będą zawierały nasze macierze wykorzystane do obliczeń.  Za pomocą procesu MASTER i funkcji **initialize_matrix**, inicjalizujemy nasze macierze z plików **csv**. Następnie w pętli **upc_forall** każdy wątek przetwarza obliczenia na zaalokowanych obiektach współdzielonych. Procesy są ułożone w architekturze siatkowej - każdemu z nich odpowiada blok macierzy wejściowych. Rozpoczynamy od wstępnego przesunięcia bloków, procesy przemnażają przypisane bloki, a następnie wykonują kolejne przesunięcie. Możemy określić ile razy wykonuje się ta operacja na podstawie wymiaru naszych macierzy. Uzyskane wyniki sumujemy i zapisujemy w pomocniczej tablicy w polu o indeksie równym ID procesu. Na koniec za pomocą procesu głównego i funkcji **save_matrix** zapisujemy macierz wynikową w formacie **csv**.\n\n\n## 3. Uruchomienie\nDo przygotowania i uruchomienia rozwiązania służy plik makefile, w którym zdefiniowane są następujące komendy:\n\n- **build** - komenda kompiluje nasz program,\n- **nodes** - tworzy plik z węzłami,\n- **run** - uruchamia skompilowany program,\n- **run__verb** - jw. z parametrem verbose,\n- **clean** - usuwa utworzone przy uruchamianiu pliki.\n\n\n## 4. Zawartość katalogu\n- **main.c** - program obsługujący zadanie,\n- **makefile** - plik make pozwalający na łatwe uruchamianie,  \n- **A.csv** - pierwsza mnożona macierz,\n- **B.csv** - druga mnożona macierz,\n- **Result.csv** - przykład docelowej wynikowej macierzy,\n- **Dokumentacja.pdf** - opis i dokumentacja projektu.\n\n## 5. Materiały\n- Prezentacja - [LINK](https://docs.google.com/presentation/d/129EjYHKPv4mQ-8vRnLUJHJYR8Tuz7tanogXzLdMU2go/edit#slide=id.g11bb28a1450_2_64)\n- GitHub - [LINK](https://github.com/nerooc/upc-cannon-algorithm)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerooc%2Fupc-cannon-algorithm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnerooc%2Fupc-cannon-algorithm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerooc%2Fupc-cannon-algorithm/lists"}