Search code examples
cmpimpi-io

MPI-IO only writes data from one process


For some reason, MPI-IO is only writing the data from one of my processes out to a file. I used MPI_File_open to open the file, MPI_File_set_view to set the view for each process, and MPI_File_write_all to write the data out. When I run the code, everything seems to execute fine and without any error, but for some reason, the file output consists of garbled junk at the first line of the CSV file (it just says NULL NULL NULL a bunch and keeps repeating on the first line when I open it to read in VS Code), and the remainder of the file is the output for the second process block (since I'm using block decomposition on two processes). I can't seem to figure out why my program isn't outputting values correctly (or at least the first process) and I figured I'd ask on here.

I've attached the code here and omitted the parts that didn't apply to the problem at hand:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <mpi.h>


int main (int argc, char** argv) {

    int iproc, nproc;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &iproc);
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);

    //Inputs:
    int depth = 3;
    float p_x_error = 0.05;
    float p_z_error = 0.05;

    int max_char[] = {128, 640, 328};
    int i_max_char = max_char[(depth%3)];

    int num_data_qubits = depth * depth;
    int data_qubit_x_error[ depth + 2][ depth + 2 ];
    int data_qubit_z_error[ depth + 2  ][ depth + 2 ];
    int ancilla_qubit_value[ depth + 1 ][ depth + 1 ];

    // Parallel block decomposition variables
    int total_num_iter = pow(4, num_data_qubits);           // Total number of outer loop iterations
    int block_size = floor(total_num_iter/nproc);       // Number of iterations per process (block)

    if (total_num_iter%nproc > 0) { block_size += 1; }  // Add 1 if blocks don't divide evenly

    int iter_first = iproc * block_size;
    int iter_last = iter_first + block_size;

    MPI_Status status;
    MPI_File fh;

    char buf[i_max_char];

    //Output:
    MPI_File_open(MPI_COMM_SELF, "testfile.csv", MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
    MPI_File_set_view(fh, iproc * block_size * strlen(buf) * sizeof(char), MPI_CHAR, MPI_CHAR, "native", MPI_INFO_NULL);

    if(iproc == 0) {
        printf("Block size: %d\n", block_size);
    }

    for ( int i = iter_first; i < iter_last; i++ ) {

        // A bunch of stuff happens where values are written to the 2d arrays listed above

        char label_list[i_max_char];
        strcpy(label_list, "\n");
        char anc_name[3];

        // Output the ancilla qubit values in proper format
        int ancilla_value;
        for (int k=1; k < depth; k++) {
            if (k%2 == 0) {
                ancilla_value = (ancilla_qubit_value[depth][k] == 1) ? -1 : 1;
                sprintf(anc_name, "%d,", ancilla_value);
                strcat(label_list, anc_name);
            }
            for (int j=depth-1; j > 0; j--) {
                if (k == 1 && j%2 == 0) {
                    ancilla_value = (ancilla_qubit_value[j][k-1] == 1) ? -1 : 1;
                    sprintf(anc_name, "%d,", ancilla_value);
                    strcat(label_list, anc_name);
                } else if (k == (depth - 1) && j%2 == 1) {
                    ancilla_value = (ancilla_qubit_value[j][k+1] == 1) ? -1 : 1;
                    sprintf(anc_name, "%d,", ancilla_value);
                    strcat(label_list, anc_name);
                }
                ancilla_value = (ancilla_qubit_value[j][k] == 1) ? -1 : 1;
                sprintf(anc_name, "%d,", ancilla_value);
                strcat(label_list, anc_name);
            }
            if (k%2 == 1) {
                ancilla_value = (ancilla_qubit_value[0][k] == 1) ? -1 : 1;
                sprintf(anc_name, "%d,", ancilla_value);
                strcat(label_list, anc_name);
            }
        }

        // For printing label list:
        strcat(label_list, "\"[");
        char qubit_name[6];
        int first = 1;

        for (int k = 1; k < depth + 1; k++) {
            for (int j = depth; j > 0; j--) {
                if (data_qubit_x_error[j][k] == 1) {
                    if (first == 1) {
                        first = 0;
                    } else {
                        strcat(label_list, ", ");
                    }
                    sprintf(qubit_name, "'X%d%d'", (k-1), (depth-j));
                    strcat(label_list, qubit_name);
                }
                if (data_qubit_z_error[j][k] == 1) {
                    if (first == 1) {
                        first = 0;
                    } else {
                        strcat(label_list, ", ");
                    }
                    sprintf(qubit_name, "'Z%d%d'", (k-1), (depth-j));
                    strcat(label_list, qubit_name);
                }
            }
        }
        strcat(label_list, "]\"");

        MPI_File_write_all(fh, label_list, strlen(label_list) * sizeof(char), MPI_CHAR, MPI_STATUS_IGNORE);

    }

    MPI_File_close(&fh);
    MPI_Finalize();
    return 0;
}

Solution

  • After lots of digging, I finally found the answer. The value I used as the offset for MPI_File_set_view() was measuring the size of buf as 1 with strlen(buf) since the variable was initialized, but not populated. I remedied this by changing the offset value to (MPI_Offset) (iproc * block_size * i_max_char) so that the offset would be the correct length, which seems to have resolved the issue!