0

Currently trying to make code finding the longest common subsequence of two given strings. I have got the code working serially, however I have been tasked for homework to implement OpenMP and OpenMPI (not worried about this yet). My main goal is to get my for loop which finds the length of the given LCS to run in parallel between threads created by omp however all my attempts so far are seemingly incorrect.

I originally thought it was maybe the use of not making some variables such as I and K not private but I think as these variables aren't actually being modified, it should not matter. Ive also looked at using the collapse and reduction clause for my nested loop but still not sure on how they are fully meant to be utilised.

/**
 * Find the longest subsequence. Initially counts counts the length of the
 * longest subsequence. It then uses this length to count back and find each 
 * char that is part of the LCS.
 */
char* subseq(char** strings, int size0, int size1) {

    int count[size0 + 1][size1 + 1]; //The LCS "Table"
    int i, k;

    //Count the length of the LCS
    #pragma omp parallel shared(count) private(i, k)
    {
        #pragma omp for
        for (i = 0 ; i <= size0; i++) {
            for (k = 0; k <= size1; k++) {
                if (i == 0 || k == 0) {
                    count[i][k] = 0;
                } else if (strings[0][i - 1] == strings[1][k - 1]) {
                    count[i][k] = count[i - 1][k - 1] + 1;
                } else {
                 count[i][k] = max(count[i][k - 1], count[i - 1][k]);
                }
            }
        }
    }





    int index = count[size0][size1];
    printf("count = %d\n", index);
    char * lcs = malloc((index + 1) * sizeof(char));
    lcs[index] = '\0';
    i = size0;
    k = size1;

    //Find each char in the LCS
    while (i > 0 && k > 0) {
        if (strings[0][i - 1] == strings[1][k - 1]) {
            lcs[index - 1] = strings[0][i - 1];
            i--;
            k--;
            index--;
        } else if (count[i - 1][k] > count[i][k - 1]) {
            i--;
        } else {
            k--;
        }
    }

    return lcs;
}

Right now my two example strings are "MZJAWXU" and "XMJYAUZ" but im getting an LCS length of 2 from the program instead of the expected 4. Running valgrind also throws of a lot of uninitialised value errors however without the use of omp I get no errors.

No warnings or compiler errors.

jksk
  • 3
  • 2
  • 1
    What do your function return? How do you pass the arguments? How do you build? What, if any, warnings do you get from the compiler? And please try to create a [mcve] to show us. – Some programmer dude Sep 11 '19 at 05:13
  • I've now edited the post with the full function – jksk Sep 11 '19 at 05:38
  • Have you looked at this for help? https://github.com/taoito/lcs-parallel – Anders Cedronius Sep 11 '19 at 05:55
  • First of all, try it *without* OMP. Does it work then? If not then there's something wrong with either your code or the algorithm is implemented wrong (or wrong to begin with). Either way you should probably spend some time *debugging* the non-parallel code. – Some programmer dude Sep 11 '19 at 06:09
  • 1
    As written in the post, I have got the code working without OMP – jksk Sep 11 '19 at 13:50
  • Please present an actual [mcve]. – Zulan Sep 11 '19 at 16:07
  • As far as I can tell OpenMP is allowed to put each iteration over `i` into a separate thread. However you are accessing results from other iterations in the inner loop: `count[i][k] = max(count[i][k - 1], count[i - 1][k]);` (note the i-1). IMHO this cannot work without synchronization. – Gregor Budweiser Sep 16 '19 at 13:53

0 Answers0