while loop dependent upon a scanf result is ending prematurely - c

I'm writing a simple program in C to calculate grades and grade averages. I feed it a textfile from the command line via the "< xyz.txt" and output to another text via "> xyz_output.txt" commands. There are over 100 lines of data in the input file, but the program keeps exiting the loop around line 6 of the input for some reason... I've checked the input format several times and I can't seem to figure out why it's exiting prematurely. Here is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char pp[4];
char school[3];
int class;
int student;
int a;
int b;
int c;
int d;
int e;
int f;
int g;
int h;
int i;
int j;
int k;
int l;
int m;
int n;
int o;
int p;
int q;
int r;
float average;
int runtotal;
int grouptotal = 0;
float groupaverage;
int counter = 0;
while (scanf("%3s%2s%2i%2i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", pp, school, &class, &student, &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o, &p, &q, &r) == 22)
{
runtotal = (a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r);
average = (float)runtotal / 18;
grouptotal = grouptotal + runtotal;
counter++;
printf ("%i.\n", counter);
printf ("%s%s-%i-%i -- %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i\n", pp, school, class, student, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r);
printf ("Total score: %i\n", runtotal);
printf ("Average: %f\n", average);
printf ("Running Total: %i\n\n", grouptotal);
}
groupaverage = (float)grouptotal / counter;
printf ("Calculations complete.\nThe total score for this group was %i.\nThe average score for this group was %f.\n", grouptotal, groupaverage);
return 0;
}
and here are the first 10 lines of the actual input .txt file.
preKO6101 0 0 1 1 1 1 1 0 1 0 1 0 0 1 1 0 2 0
preHI6114 1 0 0 1 0 1 1 1 1 0 0 0 0 1 1 1 2 1
preHI5116 0 0 0 1 0 0 1 1 1 0 0 0 0 2 0 0 1 0
preHI6103 0 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1
preHI5132 0 0 0 1 1 0 1 1 1 0 0 0 0 1 0 0 0 0
preHI5109 1 0 0 1 1 0 0 1 0 0 0 0 1 1 1 2 2 1
preHI6113 2 1 1 1 1 0 1 0 0 0 1 0 1 1 1 0 0 1
preSA5116 0 1 0 1 1 2 1 2 0 0 0 0 2 1 2 0 2 2
preHI6109 0 0 0 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1
preHI5107 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 0
It seems to make it to 'preHI5109' but then exits. I have a feeling that it has to do with how I'm using scanf, but I'm not sure what I'm doing wrong. Any advice on how to fix this?

The method employed to read the data file is very sensitive to mis-alignment, parsing and I/O issues. Suggest more robust IO and parsing as certainly some small error exist in the data file. Use fgets() to control reading the line orientated data.
char buf[100];
while (fgets(buf, sizeof buf, stdin) != NULL) {
int count = sscanf(buf, "%3s%2s%2i%2i %i %i %i %i /* ... */ %i %i",
pp, school, &class, &student, &a, &b, &c, /* ... */ &q, &r);
if (count != 22) {
printf("Error %d (TBD relevant text)\n", count);
break;
}
/* continue with normal processing */
}
Other improvements
int a[18] instead of int a; int b; ...
Use loops to then scan, sum, print the 18 elements.
Use "%i" rather than "%1i". The 1 is the minimum width, so why have it?
Note: If the input file was supplied by a Prof., It would not surprise me that something intentionally bad is in it. The lesson: do not trust data input unless well vetted. User input is evil.

Related

C read big matrix from input file

Im trying to read a 40000x40000 boolean (binary) matrix from a input file and store it in a variable. After I store it in the variable, I want to write it to a file. However, with the code I wrote it takes more than a hour. Can someone help me out? I think im doing something wrong.
Code
void get_grid_values_file(bool *grid, int n, int m, char *input_filename){
FILE *in_file;
in_file = fopen(input_filename, "r");
char buffer[1];
bool search = true;
int k=0;
while(search){
fseek(in_file, k, SEEK_SET);
fread(buffer, 1, 1, in_file);
if(*buffer == '\n')
search = false;
k++;
}
int i,j;
for(i=0; i<n; i++){
for(j=0; j<m; j++){
fseek(in_file, k, SEEK_SET);
fread(buffer, 1, 1, in_file);
*((grid+i*m) + j) = atof(buffer);
k+=2;
}
}
fclose(in_file);
}
void set_grid_values_file(bool *grid, int n, int m, char *output_filename){
FILE *out_file;
out_file = fopen(output_filename, "w");
char buffer[1] = " ";
//Set n,m and spaces
int length_n= (int) (log10 (abs (n))) + 1;
char char_n[length_n];
sprintf(char_n, "%d", n);
fseek(out_file, 0, SEEK_SET);
fwrite (char_n, length_n, 1, out_file);
fseek(out_file, length_n, SEEK_SET);
fwrite (" ", 1, 1, out_file);
int length_m= (int) (log10 (abs (m))) + 1;
char char_m[length_m];
sprintf(char_m, "%d", m);
fseek(out_file, length_n+1, SEEK_SET);
fwrite (char_m, length_m, 1, out_file);
fseek(out_file, length_n+1+length_m, SEEK_SET);
fwrite ("\n", sizeof(char), 1, out_file);
//Set grid
int i,j;
int k =length_n + length_m + 2;
for(i=0; i<n; i++){
for(j=0; j<m; j++){
fseek(out_file, k, SEEK_SET);
buffer[0] = (*((grid+i*m) + j) == true ? '1' : '0');
fwrite (buffer, 1, 1, out_file);
k++;
fseek(out_file, k, SEEK_SET);
fwrite (" ", 1, 1, out_file);
k++;
}
fseek(out_file, k, SEEK_SET);
fwrite ("\n", sizeof(char), 1, out_file);
k++;
}
}
int main(int argc, char *argv[])
{
char *input_filename = "gen0_40kx40k.in";
char *output_filename = "gol_output.out";
int n = 40000;
int m = 40000;
bool *grid = (bool *)malloc(n*m*sizeof(bool));
//Read
get_grid_values_file((bool *)grid, n, m, input_filename);
//Write
set_grid_values_file((bool *)grid, n, m, output_filename);
return 0;
}
Input format, the first line contains the dem of the 2d matrix:
20 20
1 0 1 0 0 1 0 0 1 0 1 0 1 0 1 1 0 1 0 0
1 1 0 0 0 0 0 1 0 1 1 1 1 0 0 1 0 0 1 1
0 1 1 0 1 0 1 1 0 0 0 1 1 0 0 1 1 0 0 1
1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 0 1 1 1 1
1 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 1 1
1 1 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 1 0 1
1 1 1 0 0 0 1 1 1 0 0 1 1 1 1 1 0 0 1 1
0 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 0 0 1
1 0 0 0 0 1 1 0 1 1 1 1 0 1 1 1 0 0 0 0
1 1 0 0 0 1 1 0 0 1 1 1 1 1 1 1 0 1 1 0
0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 1 1 1 1 1
0 0 0 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 1 0
1 0 0 1 0 0 0 1 1 1 0 1 1 0 0 0 1 1 0 0
0 1 0 1 0 1 1 0 0 0 0 1 1 0 1 1 0 1 0 1
1 0 0 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1 1 1
1 1 1 0 1 0 1 1 1 1 0 0 1 0 1 1 0 0 1 0
1 0 0 1 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 1
0 0 0 1 0 1 1 1 1 0 1 0 0 0 1 1 0 0 0 1
1 1 1 0 1 0 1 1 1 0 1 1 0 1 0 1 0 1 0 1
1 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 0 1 0 1
Read larger chunks from the input file - not every char as a separate call. Eg a complete row of your matrix at once.
Why do you use in the inner loop of set_grid_values_file two fwrite calls. Better to combine them:
char buffer[2] = " ";
for(i=0; i<n; i++){
int base = grid+i*m;
for(j=0; j<m; j++){
fseek(out_file, k, SEEK_SET);
buffer[0] = (*(base + j) ? '1' : '0');
fwrite (buffer, 1, 2, out_file);
k+=2;
}
I would suggest removing the calls to fseek.
while(search){
// Make sure the read is successful. Otherwise, break out of the loop.
if ( fread(buffer, 1, 1, in_file) != 1 )
{
break;
}
if(*buffer == '\n')
search = false;
k++;
}
int i,j;
// Rewind the file
fseek(in_file, 0, SEEK_SET);
for(i=0; i<n; i++){
for(j=0; j<m; j++){
// Make sure the read is successful. Otherwise, break out of the loop.
if ( fread(buffer, 1, 1, in_file) != 1 )
{
break;
}
*((grid+i*m) + j) = atof(buffer);
k+=2;
}
}
Also atof(buffer) is a problem when buffer has only one element in it. Use at least a two element array.
char buffer[2] = {0};
This is about the simplest(and possibly the fastest) method.
stdio is buffered, getc() is most probably a macro
function calls are costly (they trash the instruction pipeline and cache) ; you use 1seek+1fread per boolean bit read.
you dont need to seek the file; just read it sequentially and put the values at the correct{row,col} positions.
setting and testing an indicator variable (your search) is a waste of time (often taught in Pascal and Java classes...) ;instead: just jump out of the loop (or continue)
I am assuming an ASCII file with spaces between the values, but without the{nrow,ncol} at the top (the{n,m}values are supplied as function arguments)
void get_grid_values_file(bool *grid, int n, int m, char *input_filename)
{
unsigned col,row;
FILE * fp;
fp= fopen (input_filename, "r" );
if(!fp)return;
for(row=col=0; ; ) {
int ch;
ch=getc(fp);
if (ch == EOF)break;
if (ch < '0' || ch > '1') continue;
grid[row*m+col++] = (ch == '0') ? False :True;
if (col == m) {col=0; row++; }
if (row == n) break;
}
fclose(fp);
return;
}

Scanf with optional text

I'm trying to read a .txt file, which contains a name and a last name in the first line and below contains an array
The problem is that the first line may or may not one letter A in brackets like this: [A].
for instance:
Jose Perez [A] or may have jose perez
When I run here mentioned code, if the first line does not contain a [A] performs a shift of values, for example the value of the matrix [1] [1] is up as tester and insert a 0 at the end to complete the matrix.
Here is a sample of what gives the code when there is a [A] in the first line and when not
FILE* text=NULL;
text=fopen(archivo,"r");
char name[100];
char last_name [100];
char verifier [10];
int matriz[6][4];
int i ;
int lu,ma,mi,ju,vi;
if (text == NULL) {
}
else {
fscanf(text,"%s %s %s [^\n]",name, last_name, verifier);
for( i= 0; i<7;i++){
fscanf(text,"%d %d %d %d %d [^\n]",&lu, &ma, &mi,&ju,&vi);
matriz[i][0] = lu;
matriz[i][1] = ma;
matriz[i][2] = mi;
matriz[i][3] = ju;
matriz[i][4] = vi;
}
Result:
Jose Perez 1
0 0 0 0 0
1 0 1 0 1
0 1 1 1 1
0 1 1 0 0
1 0 0 0 0
1 1 1 0 0
1 0 1 0 0
Juan Perez A
1 0 1 1 1
0 0 1 1 1
0 0 1 0 1
0 0 1 1 1
1 0 1 0 1
0 0 1 1 1
0 1 1 1 0
As could be solved?
char line[80], fname[16], lname[16], third[4];
fgets(line, 80, fp)
if (sscanf(line, "%s %s %s\n",
fname, lname, third) == 3 && strcmp(third, "[A]") == 0)
// the line has a [A] at the end
else if (sscanf(line, "%s %s\n", fname, lname) == 2)
// the line does not have a [A] at the end
else
fprintf(stderr, "Invalid line");
fgets reads the next line from the file. If it is not null, we check the return value of sscanf. It returns the number of items parsed. So, on success it should return 3. If it contains a [A] at the end of the line, the third variable should compare equal to [A].
After all this, we can proceed to read the array.
Since your verifier is always a single character, you can let scanf do the work. In the example below it will stop scanning if the opening bracket does not exist, but get the verifier character otherwise:
char name[100];
char last_name [100];
char verifier = 0;
int n = fscanf("%s %s [%c]", name, last_name, &verifier);
If n == 2 there was no verifier, if n == 3 there was a verifier, and in any other case, there was an error.

Generate Binary Sequence

I want to generate permutations of string of 5 0s followed by the permutations of 4 0s and a single 1, followed by the permutations of 3 0s with 2 1s etc? My code is as follows:
#include<stdio.h>
int main(){
int i,j,k,l,s[5];
for(i=0;i<5;i++)
s[i]=0;
for(k=0;k<5;k++)
printf("%d ",s[k]);
printf("\n");
printf("---------------------------------------------\n");
for(i=0;i<5;i++){
for(j=0;j<5;j++)
if(i==j)
s[j]=1;
else
s[j]=0;
for(k=0;k<5;k++)
printf("%d ",s[k]);
printf("\n");
}
printf("---------------------------------------------\n");
for(i=0;i<5;i++){
for(k=0;k<5;k++)
s[k]=0;
s[i]=1;
for(j=i+1;j<5;j++){
s[j]=1;
for(k=0;k<5;k++)
printf("%d ",s[k]);
printf("\n");
for(k=j;k<5;k++)
s[k]=0;
}
}
printf("---------------------------------------------\n");
for(i=0;i<5;i++){
for(j=i+1;j<5;j++){
for(k=0;k<5;k++)
s[k]=0;
s[i]=1;
s[j]=1;
for(l=j+1;l<5;l++){
s[l]=1;
for(k=0;k<5;k++)
printf("%d ",s[k]);
printf("\n");
for(k=l;k<5;k++)
s[k]=0;
}
}
}
}
So output is
0 0 0 0 0
---------------------------------------------
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
---------------------------------------------
1 1 0 0 0
1 0 1 0 0
1 0 0 1 0
1 0 0 0 1
0 1 1 0 0
0 1 0 1 0
0 1 0 0 1
0 0 1 1 0
0 0 1 0 1
0 0 0 1 1
---------------------------------------------
1 1 1 0 0
1 1 0 1 0
1 1 0 0 1
1 0 1 1 0
1 0 1 0 1
1 0 0 1 1
0 1 1 1 0
0 1 1 0 1
0 1 0 1 1
0 0 1 1 1
Output is ok. However in my code I use
different for loops for different cases.
Is it possible to use better approach so
that length of the code is reduced?
One approach follows. This solution needs O(n) space and each output string requires O(n) time.
#include <stdio.h>
#include <stdlib.h>
char *buf;
// Print combinations of m 1's in a field of n 0/1's starting at s.
void print_combinations(char *s, int n, int m)
{
// If there is nothing left to append, we are done. Print the buffer.
if (m == 0 && n == 0) {
*s = '\0';
printf("%s\n", buf);
return;
}
// Cut if there are more 1's than positions left or negative numbers.
if (m > n || m < 0 || n < 0) return;
// Append a 0 and recur to print the rest.
*s = '0';
print_combinations(s + 1, n - 1, m);
// Now do the same with 1.
*s = '1';
print_combinations(s + 1, n - 1, m - 1);
}
int main(void)
{
int n = 5;
buf = malloc(n + 1);
for (int m = 0; m <= n; m++) {
print_combinations(buf, n, m);
printf("-----\n");
}
return 0;
}
You could use a recursive function like so - you don't have to print the result when finished, you could add it to a list etc.
The function works by starting with an empty string. At each step you add one more character - in this case you add either a 0 or a 1.
If a 1 is added we account for this by decrementing the ones value on the next call to the function. (In a more general case you could pass a list of all the elements to be permuted - then the process would be to pick from this list, add it to your permutation and remove it from the list. You repeat that until the list is empty and you have permuted all of the elements in the list.)
When the string reaches the desired length we have finished and so we return.
#include <stdio.h>
void recurse(char *str, int length, int maxLength, int ones)
{
if (length == maxLength)
{
// we are finished
printf("%s\n", str);
return;
}
if (ones > 0)
{
// put a 1 into the new string
str[length] = '1';
recurse(str, length + 1, maxLength, ones - 1);
}
if (ones < maxLength - length)
{
// there are still spaces for 0s
// put a 0 into the string
str[length] = '0';
recurse(str, length + 1, maxLength, ones);
}
}
int main()
{
const int maxLength = 5;
char buffer[maxLength + 1];
buffer[maxLength] = 0;
int ones;
for (ones = 0; ones <= maxLength; ones++)
{
printf("Ones: %i\n", ones);
recurse(buffer, 0, maxLength, ones);
printf("\n");
}
return 0;
}
The output looks like this:
Ones: 0
00000
Ones: 1
10000
01000
00100
00010
00001
Ones: 2
11000
10100
10010
10001
01100
01010
01001
00110
00101
00011
Ones: 3
11100
11010
11001
10110
10101
10011
01110
01101
01011
00111
Ones: 4
11110
11101
11011
10111
01111
Ones: 5
11111
Finally, unless you really want to/need to learn/use C, I would recommend using C++ because you get really nice features like std::vector and std::set and so many other things which will make your life so much easier. I would have written this completely different in C++.

Extra edge in my list?

I'm writing code to create a matrix out of a list of edges.
However, when I run said code, I get a "phantom edge" that is not in the input data, which goes on to screw up the rest of my program. The edge is 9,2 in the matrix, or 8,1 in elemental code form.
All elements in the matrix are initialized to 0 before hand.
Here is the input data to do with the matrix:
1 2
1 8
2 8
3 5
3 1
4 5
4 6
5 2
5 9
6 4
6 8
7 4
7 10
8 4
8 6
9 4
9 5
10 7
10 3
Here are the functions that handle the input:
void displayMatrix(int **matrix, int numberVertices){ //function displays the matrix
int i, j;
for(i=0; i<numberVertices; i++) //go through eveyr element
{
for(j=0; j<numberVertices; j++)
{
printf("%d ", matrix[i][j]); //print element
}
printf("\n");
}
printf("\n\n");
}
void inputMatrix(FILE *fp, int ** matrix) //file places value 1 into matrix if edge exists for the adjacency matrix
{
int e1, e2;
while(!feof(fp)) //continue to the end of the file
{
fscanf(fp, "%d %d", &e1, &e2); //get pairs
e1 = e1 - 1; //adjust the edges for array use
e2 = e2 - 1;
matrix[e1][e2] = 1; //place value 1 into appropriate location in adjacency matrix
}
fclose(fp); //close the file connection
}
0 1 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1 0 0
1 0 0 0 1 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 1 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 1 0 0
0 0 0 1 0 0 0 0 0 1
0 0 0 1 0 1 0 0 0 0
0 *1 0 1 1 0 0 0 0 0
0 0 1 0 0 0 1 0 0 0
*the entry that should not exist, not in the input data
The problem is that you're looping one more additional time than necessary, causing fscanf to fail before the first conversion and thus leaving e1 and e2 as they were from the prior read. As it turns out, the last entry has e1 set to 10 and e2 to 3, so e1 becomes 9 and e2 becomes 2, thus causing your phantom edge.
The cause of this additional loop is because your loop condition doesn't do what you think it does. feof checks if the end-of-file flag has been set, and this can only be set when attempting to read at the end of the file. Since you're checking for end-of-file before your read, you're not actually picking up on this until the next iteration, thus you loop an additional time. The proper correction is very simple; just continue until fscanf results in EOF.
while (fscanf(fp, "%d %d", &e1, &e2) != EOF)
{
matrix[e1 - 1][e2 - 1] = 1;
}
As pointed out in the comments, you're not testing for errors in fscanf.
In particular, you have not yet reached the end of file after reading 10 3, presumably because a newline was encountered.
However, in the next time around fscanf will return zero. Then you subtract 1 from those values (which were not read) to get 9 2.
You can make sure that two integers were read by doing this:
if( 2 != fscanf(fp, "%d %d", &e1, &e2) ) break;
You can try this:
fscanf(fp, "%d %d\n", &e1, &e2);
When you finish the last two digit, there is one more \n,the loop have to continue,this will make trouble

Sending blocks of 2D array rows using MPI in C

I am trying to do a matrix multiplication using MPI in C. (c <= a*b)
I am running the following code on 4 nodes. All the matrices are 8*8 in size.
(num of rows in a matrix % num of nodes == 0)
matrix b[][] is broadcast so all the nodes get the same copy. For matrix a[][], instead of broadcasting, I want to send only the set of rows that is needed by each node.
But when I run the following code and print the matrix a[][] after MPI_Recv() worker nodes print 0s instead of the values assigned in the master node.
Can you point out what am I doing wrong here?
#include <stdio.h>
#include "mpi.h"
#include "matrix.c" // matrix definitions and matrix operation functions are here
int main(int argc, char *argv[])
{
MPI_Status status;
int num, rank, size, tag, high,low,i;
int offset, tmphigh,rows;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
rows=MAX/size; // MAX is the length(=height) of the matrices
tag = 201;
low=rank*rows;
high=low+rows;
if (rank == 0) {
fillMatrix(b,MAX);
fillMatrix(a,MAX);
}
MPI_Bcast(&b[0][0],MAX*MAX,MPI_INT,0,MPI_COMM_WORLD);
if(rank==0){
for(i=1;i<size;i++){
offset=i*rows;
MPI_Send(&a[offset][0],rows*MAX,MPI_INT,i,tag,MPI_COMM_WORLD);
}
}else{
MPI_Recv(&a[low][0],rows*MAX,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
}
printMatrix(a,MAX);
MPI_Finalize();
return 0;
}
here is how matrices are created
int a[MAX][MAX], b[MAX][MAX], c[MAX][MAX];
int len; //(edited after Jeremy W. Sherman's comment )
//this was the reason that caused this problem. changing this to int len=MAX; solved the problem
void fillMatrix(int (*matrix)[len], int len){
int i=0,j=0;
for(i=0;i<len;i++){
for(j=0;j<len;j++){
matrix[i][j]=j;
}
}
//printMatrix(matrix,len);
}
Thank You.
The problem might lie printMatrix() and fillMatrix(). clang refused to compile your definition of fillMatrix():
so_mpi.c:22:31: error: use of undeclared identifier 'len'
void fillMatrix(int (*matrix)[len], int len){
^
Dropping len from the prototype just creates another problem:
so_mpi.c:26:19: error: subscript of pointer to incomplete type 'int []'
matrix[i][j]=j;
~~~~~~^
What did work was this:
void fillMatrix(int *matrix, int len) {
int i, j;
for (i = 0; i < len; ++i) {
int *row = &matrix[i * len];
for(j = 0; j < len; ++j) {
row[j] = j;
}
}
}
fillMatrix((int *)a, MAX);
fillMatrix((int *)b, MAX);
With that change, everything seems to work fine. I used MAX = 5 and 5 nodes. I prefixed logging statements with the node's rank and added a few more logging statements. Here was the result:
$ mpirun -np 5 ./so_mpi
node 1 of 5
node 4 of 5
node 0 of 5
0: filling matrices
0: matrix B:
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0: matrix A:
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0: broadcast of B complete
0: sending 1 rows (5 elements) of A to node 1
0: sending 1 rows (5 elements) of A to node 2
0: sending 1 rows (5 elements) of A to node 3
0: sending 1 rows (5 elements) of A to node 4
0: matrix A:
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
1: broadcast of B complete
1: received portion of matrix
1: matrix A:
0 0 0 0 0
0 1 2 3 4
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
node 2 of 5
2: broadcast of B complete
2: received portion of matrix
2: matrix A:
0 0 0 0 0
0 0 0 0 0
0 1 2 3 4
0 0 0 0 0
0 0 0 0 0
node 3 of 5
3: broadcast of B complete
3: received portion of matrix
3: matrix A:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 1 2 3 4
0 0 0 0 0
4: broadcast of B complete
4: received portion of matrix
4: matrix A:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 1 2 3 4

Resources