So I'm trying to add vectors like this.. 5 elements into 2 groups so the result would be like [[0, 1,2], [3, 4]]..
However, I get [[0, 2], [0, 1]]
I can't seem to figure out why the output is printed this way..
for _k in 0..num_partitions-1{
let mut x_y : Vec<usize> = Vec::new();
for i in 0..partition_size{
x_y.push(v[ss]);
if add <= ex && ex != 0 && ss != partition_size{
//push extra to the first few
x_i.push(v[ss]);
//x_y.push(v[add]);
increment(&mut ss);
if add <= ex && ss != partition_size{
x_i.push(v[ss]);
//x_y.push(v[ss]);
add+=1;
increment(&mut ss);
}
}
else if add >= ex && ss != partition_size{
for i in 0..partition_size{
x_i.push(v[ss]);
increment(&mut ss);
}
/*x_i.push(v[ss]);
increment(&mut ss);*/
}
}
ks.push(x_y);
}
ks.push(x_i);
It is almost impossible to understand your code like this. You should try to provide a complete code example. Optimal would be either a playground link or, if this is part of a larger project, e.g. a link to a github repo. Try to create a test or a main function that calls into this code and prints the result (or uses assert_eq, etc), so that we can witness the result of "[[0, 2], [0, 1]]" the same way that you did.
Here's the entire code (I ran it like this: ./main 5 2)
use std::env; // to get arugments passed to the program
use std::thread;
//use std::time::Duration;
/*
* Print the number of partitions and the size of each partition
* @param vs A vector of vectors
*/
fn print_partition_info(vs: &Vec<Vec<usize>>){
println!("Number of partitions = {}\n", vs.len());
for i in 0..vs.len(){
println!("\tsize of partition {} = {}", i, vs[i].len());
}
}
/*
* Create a vector with integers from 0 to num_elements -1
* @param num_elements How many integers to generate
* @return A vector with integers from 0 to (num_elements - 1)
*/
fn generate_data(num_elements: usize) -> Vec<usize>{
let mut v : Vec<usize> = Vec::new();
for i in 0..num_elements {
v.push(i);
}
return v;
}
/*
* Partition the data in the vector v into 2 vectors
* @param v Vector of integers
* @return A vector that contains 2 vectors of integers
*/
fn partition_data_in_two(v: &Vec<usize>) -> Vec<Vec<usize>>{
let partition_size = v.len() / 2;
// Create a vector that will contain vectors of integers
let mut xs: Vec<Vec<usize>> = Vec::new();
// Create the first vector of integers
let mut x1 : Vec<usize> = Vec::new();
// Add the first half of the integers in the input vector to x1
for i in 0..partition_size{
x1.push(v[i]);
}
// Add x1 to the vector that will be returned by this function
xs.push(x1);
// Create the second vector of integers
let mut x2 : Vec<usize> = Vec::new();
// Add the second half of the integers in the input vector to x2
for i in partition_size..v.len(){
x2.push(v[i]);
}
// Add x2 to the vector that will be returned by this function
xs.push(x2);
// Return the result vector
xs
}
/*
* Sum up the all the integers in the given vector
* @param v Vector of integers
* @return Sum of integers in v
* Note: this function has the same code as the reduce_data function.
* But don't change the code of map_data or reduce_data.
*/
fn map_data(v: &Vec<usize>) -> usize{
let mut sum = 0;
for i in v{
sum += i;
}
sum
}
/*
* Sum up the all the integers in the given vector
* @param v Vector of integers
* @return Sum of integers in v
*/
fn reduce_data(v: &Vec<usize>) -> usize{
let mut sum = 0;
for i in v{
sum += i;
}
sum
}
/*
* A single threaded map-reduce program
*/
fn main() {
// Use std::env to get arguments passed to the program
let args: Vec<String> = env::args().collect();
if args.len() != 3 {
println!("ERROR: Usage {} num_partitions num_elements", args[0]);
return;
}
let num_partitions : usize = args[1].parse().unwrap();
//println!("partitions {}", num_partitions);
let num_elements : usize = args[2].parse().unwrap();
//println!("elements {}", num_elements);
if num_partitions < 1{
println!("ERROR: num_partitions must be at least 1");
return;
}
if num_elements < num_partitions{
println!("ERROR: num_elements cannot be smaller than num_partitions");
return;
}
// Generate data.
let v = generate_data(num_elements);
// PARTITION STEP: partition the data into 2 partitions
let xs = partition_data_in_two(&v);
// Print info about the partitions
println!("VEC {:?}", xs);
print_partition_info(&xs);
let mut intermediate_sums : Vec<usize> = Vec::new();
// MAP STEP: Process each partition
// CHANGE CODE START: Don't change any code above this line
// Change the following code to create 2 threads that run concurrently and each of which uses map_data() function to process one of the two partitions
let part1 = xs[0].clone();
let t1 = thread::spawn(move || {map_data(&part1)});
let part2 = xs[1].clone();
let t2 = thread::spawn(move || {map_data(&part2)});
let res1 = t1.join().unwrap();
let res2 = t2.join().unwrap();
intermediate_sums.push(res1);
intermediate_sums.push(res2);
// CHANGE CODE END: Don't change any code below this line until the next CHANGE CODE comment
// Print the vector with the intermediate sums
println!("Intermediate sums = {:?}", intermediate_sums);
// REDUCE STEP: Process the intermediate result to produce the final result
let sum = reduce_data(&intermediate_sums);
println!("Sum = {}\n", sum);
// CHANGE CODE: Add code that does the following:
// 1. Calls partition_data to partition the data into equal partitions
// 2. Calls print_partition_info to print info on the partitions that have been created
// 3. Creates one thread per partition and uses each thread to concurrently process one partition
// 4. Collects the intermediate sums from all the threads
// 5. Prints information about the intermediate sums
// 5. Calls reduce_data to process the intermediate sums
// 6. Prints the final sum computed by reduce_data
//clear the vector (removing the 2 intermediate sums before)
intermediate_sums.clear();
println!("PIE");
let _ks = partition_data(num_partitions,&v);
//create new threads
//x starts at 0
//let numb : usize = args[1].parse().unwrap();
//thread::spawn(move || {map_data(&part1)});
let nn = 0;
//let mut vv : Vec<usize> = Vec::new();
let mut vv=Vec::new();
for _i in 0..num_partitions{
let p2 = _ks[nn].clone();
let tt2 = thread::spawn(move || {map_data(&p2)});
vv.push(tt2)
}
for entry in vv{
intermediate_sums.push(entry.join().unwrap());
//println!("Intermediate sums = {:?}", intermediate_sums);
}
println!("Intermediate sums = {:?}", intermediate_sums);
let fin = reduce_data(&intermediate_sums);
println!("Final Sum = {:?}\n", fin);
}
fn increment(n: &mut usize) {
*n += 1;
}
/*
* CHANGE CODE: code this function
* Note: Don't change the signature of this function
*
* Partitions the data into a number of partitions such that
* - the returned partitions contain all elements that are in the input vector
* - if num_elements is a multiple of num_partitions, then all partitions must have equal number of elements
* - if num_elements is not a multiple of num_partitions, some partitions can have one more element than other partitions
*
* @param num_partitions The number of partitions to create
* @param v The data to be partitioned
* @return A vector that contains vectors of integers
*
*/
fn partition_data(num_partitions: usize, v: &Vec<usize>) -> Vec<Vec<usize>>{
// Remove the following line which has been added to remove a compiler error
println!("Number of Partitions: {:?}\n", num_partitions);
println!("VECTOR {:?}", v.len());
//num = partition_data_in_two(v)
let partition_size = v.len() / num_partitions;
let ex = v.len() % num_partitions;
//println!("{}",ex);
let mut ss = 0;
let mut add = 0;
println!("EX {}", ex);
for i in 0..num_partitions{
//let pie = partition_size + extra;
if i < ex{
println!("\tsize of partition {} = {}", i, partition_size+1);
}
else{
println!("\tsize of partition {} = {}", i, partition_size);
}
}
// Create a vector that will contain vectors of integers
let mut ks: Vec<Vec<usize>> = Vec::new();
// Add the first half of the integers in the input vector to x1
let mut x_i : Vec<usize> = Vec::new();
for _k in 0..num_partitions-1{
let mut x_y : Vec<usize> = Vec::new();
for i in 0..partition_size{
x_y.push(v[ss]);
if add <= ex && ex != 0 && ss != partition_size{
//push extra to the first few
x_i.push(v[ss]);
//x_y.push(v[add]);
increment(&mut ss);
if add <= ex && ss != partition_size{
x_i.push(v[ss]);
//x_y.push(v[ss]);
add+=1;
increment(&mut ss);
}
}
else if add >= ex && ss != partition_size{
for i in 0..partition_size{
x_i.push(v[ss]);
increment(&mut ss);
}
/*x_i.push(v[ss]);
increment(&mut ss);*/
}
}
ks.push(x_y);
}
ks.push(x_i);
println!("VEC {:?}", ks);
ks
}
/* for j in 0..num_partitions{
let mut x_y : Vec<usize> = Vec::new();
x_y.push(v[ss]);
if ex == 0{
increment(&mut ss);
x_y.push(v[ss]);
x_i.push(v[ss]);
}
else{
increment(&mut ss);
x_i.push(v[ss]);
}
increment(&mut ss);
ks.push(x_y);
}*/
/*
else if _y > ex && ss != partition_size{
x_i.push(v[ss]);
increment(&mut ss);
println!{"HI1 {}",ss}
}
*/
/*
for _i in 0..partition_size{
let mut x_i : Vec<usize> = Vec::new();
//let mut exx : Vec<usize> = Vec::new();
for _y in 0..partition_size{
//x_i.push(v[ss]);
if _y < ex && ss != partition_size+1{
//push extra to the first few
x_i.push(v[ss]);
println!{"HI {}",ss}
increment(&mut ss);
}
else if _y > ex && ss != partition_size+1{
x_i.push(v[ss]);
println!{"HI1 {}",ss}
increment(&mut ss);
}
else{
println!{"HI21 {}",ss}
//increment(&mut ss);
}
}
ks.push(x_i);
}
*/
for _k in 0..num_partitions - 1 {
let mut x_y: Vec<usize> = Vec::new();
for i in 0..partition_size {
x_y.push(v[ss]);
+ increment(&mut ss);
if add <= ex && ex != 0 && ss != partition_size {
//push extra to the first few
x_i.push(v[ss]);
//x_y.push(v[add]);
increment(&mut ss);
if add <= ex && ss != partition_size {
x_i.push(v[ss]);
//x_y.push(v[ss]);
add += 1;
increment(&mut ss);
}
} else if add >= ex && ss != partition_size {
for i in 0..partition_size {
x_i.push(v[ss]);
increment(&mut ss);
}
/*x_i.push(v[ss]);
increment(&mut ss);*/
}
}
ks.push(x_y);
}