diff --git a/Cargo.lock b/Cargo.lock index 7af5bf7..77b0761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,16 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "assignment-01" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "itertools", + "rayon", +] + [[package]] name = "assignment-03" version = "0.1.0" @@ -518,16 +528,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "rust" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "itertools", - "rayon", -] - [[package]] name = "rustc-hash" version = "1.1.0" diff --git a/Dockerfile b/Dockerfile index 78be7f0..51e705d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,5 +30,6 @@ COPY --from=typst /bin/typst /usr/bin/typst RUN curl https://sh.rustup.rs -sSf | bash -s -- -y RUN /root/.cargo/bin/cargo install cargo-watch +RUN /root/.cargo/bin/cargo install watchexec RUN echo 'eval "$(direnv hook bash)"' >> /root/.bashrc \ No newline at end of file diff --git a/assignments/01/rust/Cargo.toml b/assignments/01/rust/Cargo.toml index b0d967d..97f6dbc 100644 --- a/assignments/01/rust/Cargo.toml +++ b/assignments/01/rust/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rust" +name = "assignment-01" version = "0.1.0" edition = "2021" diff --git a/assignments/03/.clangd b/assignments/03/.clangd new file mode 100644 index 0000000..d81ad1a --- /dev/null +++ b/assignments/03/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: -I/usr/lib/aarch64-linux-gnu/openmpi/include -I/usr/lib/aarch64-linux-gnu/openmpi/include/openmpi diff --git a/assignments/03/.gitignore b/assignments/03/.gitignore new file mode 100644 index 0000000..00b0e11 --- /dev/null +++ b/assignments/03/.gitignore @@ -0,0 +1,3 @@ +lpa +compile_commands.json +.cache \ No newline at end of file diff --git a/assignments/03/Makefile b/assignments/03/Makefile new file mode 100644 index 0000000..2531573 --- /dev/null +++ b/assignments/03/Makefile @@ -0,0 +1,7 @@ +.PHONY: run + +lpa: lpa.c + mpicc -o $@ -g $< + +run: + watchexec -c clear 'make lpa && mpirun -n 4 ./lpa dataset/1000.txt' \ No newline at end of file diff --git a/assignments/03/lpa.c b/assignments/03/lpa.c index c272dab..a69cefd 100644 --- a/assignments/03/lpa.c +++ b/assignments/03/lpa.c @@ -1 +1,122 @@ -int main() {} \ No newline at end of file +#include +#include +#include +#include +#include + +typedef struct { + int fst; + int snd; +} pair; +void init_pair_type(MPI_Datatype *out); + +int main(int argc, char **argv) { + MPI_Init(&argc, &argv); + int rank, p; + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &p); + + MPI_Datatype IntPairType; + init_pair_type(&IntPairType); + +// One process reads the file and distributes the data to the other processes +// using a 1D decomposition (each rank gets approx same number of vertices). +#pragma region + FILE *fp; + char *line = NULL; + size_t len; + ssize_t read; + pair params; + + if (rank == 0) { + + printf("Hello\n"); + fp = fopen(argv[1], "r"); + if ((read = getline(&line, &len, fp)) != -1) + sscanf(line, "%d %d", ¶ms.fst, ¶ms.snd); + } + + // Send this pair + MPI_Bcast(¶ms, 1, IntPairType, 0, MPI_COMM_WORLD); + int num_nodes = params.fst; + int num_edges = params.snd; + + int max_num_my_edges = (num_edges / p) + p; + pair my_edges[max_num_my_edges]; + + // Read the edges + pair edges[num_edges]; + int my_count; + int counts[p], displs[p]; + if (rank == 0) { + + line = NULL; + for (int i = 0; i < num_edges; ++i) { + getline(&line, &len, fp); + sscanf(line, "%d %d", &edges[i].fst, &edges[i].snd); + } + + int step = num_edges / p; + for (int i = 0; i < p; ++i) { + int start = i * step; + int end = i == p - 1 ? num_edges : start + step; + int count = end - start; + + counts[i] = count; + displs[i] = start; + } + } + + MPI_Scatter(counts, 1, MPI_INT, &my_count, 1, MPI_INT, 0, MPI_COMM_WORLD); + printf("[%d] #: %d\n", rank, my_count); + + MPI_Scatterv(edges, counts, displs, IntPairType, my_edges, my_count, + IntPairType, 0, MPI_COMM_WORLD); + + if (rank == 0) { + fclose(fp); + if (line) + free(line); + } +#pragma endregion + +// Each process analyzes the non-local edges that are contained in its portion +// of the graph. +#pragma region +#pragma endregion + +// Each process determines which processors stores the non-local vertices +// corresponding to the non-local edges. +#pragma region +#pragma endregion + +// All the processes are communicating to figure out which process needs to +// send what data to the other processes. +#pragma region +#pragma endregion + +// The processes perform the transfers of non-local labels and updates of +// local labels until convergence. +#pragma region +#pragma endregion + +// The results are gathered to a single process, which writes them to the +// disk. +#pragma region +#pragma endregion + MPI_Finalize(); + return 0; +} + +void init_pair_type(MPI_Datatype *out) { + int blocklengths[2] = {1, 1}; + MPI_Datatype types[2] = {MPI_INT, MPI_INT}; + MPI_Aint offsets[2]; + + offsets[0] = offsetof(pair, fst); + offsets[1] = offsetof(pair, snd); + + MPI_Type_create_struct(2, blocklengths, offsets, types, out); + MPI_Type_commit(out); +} \ No newline at end of file diff --git a/assignments/03/rust/src/main.rs b/assignments/03/rust/src/main.rs index a9551eb..930b1a7 100644 --- a/assignments/03/rust/src/main.rs +++ b/assignments/03/rust/src/main.rs @@ -32,7 +32,13 @@ fn main() -> Result<()> { // One process reads the file and distributes the data to the other processes // using a 1D decomposition (each rank gets approx same number of vertices). - let mut this_process_edges = Vec::::new(); + let mut this_process_edges = vec![ + Edge { + from_node: 0, + to_node: 0, + }; + 1000 + ]; if rank == root_rank { let file = File::open(opt.graph_file)?; let mut reader = BufReader::new(file); @@ -45,10 +51,11 @@ fn main() -> Result<()> { let mut edges = Vec::with_capacity(num_edges); for _ in 0..num_edges { + line.clear(); reader.read_line(&mut line)?; let parts = line.trim().split_ascii_whitespace().collect::>(); let from_node: usize = parts[0].parse()?; - let to_node: usize = parts[0].parse()?; + let to_node: usize = parts[1].parse()?; let edge = Edge { from_node, to_node }; edges.push(edge); } @@ -65,16 +72,18 @@ fn main() -> Result<()> { start + step }; let this_process_num_edges = end - start; + println!( "[{process}/{size}] shiet {start}..{end} ({this_process_num_edges})" ); + counts.push(this_process_num_edges as Count); displs.push(start as Count); } + println!("Sending {displs:?}..."); let partition = Partition::<[Edge], _, _>::new(edges.as_slice(), counts, displs); - println!("Sending..."); root_process .scatter_varcount_into_root(&partition, &mut this_process_edges); } else { @@ -102,7 +111,7 @@ fn main() -> Result<()> { Ok(()) } -#[derive(Debug, Equivalence)] +#[derive(Copy, Clone, Debug, Equivalence)] struct Edge { from_node: usize, to_node: usize,