2014-11-11 3 views
-4

Застревает в блоке, расположенном ниже, под // шагом 5, проблема заключается в том, что код не будет продвигаться в или после данного блока if. Мне нужно выяснить, как решить эту проблему до начала создания параллельного кода. Если вы запустите код, вы увидите один оператор печати, который указывает значение «один» и еще два для «i» и «j». После того, как начнется блок if, ни один из других операторов печати не попадет. В результате я довольно застрял, я знаю, что это конкретная проблема, однако я не могу определить, почему это причина.Код CUDA не обрабатывается, если блок правильно

Любая помощь приветствуется! Спасибо заранее!

Образец входного файла.

>386.fasta.screen.Contig1 
GAGTTTGATCCTGGCTCAGAATCAACGCTGGCGGCGCGCTTAACACATGC 
AAGTCGAACGAGAAAGTGGAGCAATCCATGAGTACAGTGGCGTACGGGTG 
AGTAACACGTGGGTAATCTACCTCTTAGTGGGGAATAACTTTGGGAAACC 
GAAGCTAATACCGCATAAGCTCGAGAGAGGAAAGCAGCAATGCGCTGAGA 
GAGGAGCCCGCGGCCGATTAGCTAGTTGGCAGGGTAAAAGCCTACCAAGG 
CAGAGATCGGTAGCCGGCCTGAGAGGGCACACGGCCACACTGGCACTGAA 
ACACGGGCCAGACTCCTACGGGAGGCAGCAGTGGGGAATCTTGCACAATG 
GGGGCAACCCTGATGCAGCGACGCCGCGTGAGCGATGAAGCCCTTCGGGG 
TGTAAAGCTCTTTCGTCAGGGAAGATAGTGACGGTACCTGGAGAAGCAGC 
TGCGGCTAACTACGTGCCAGCAGCCGCGGTAATACGTAGGCAGCGAGCGT 
TGTTCGGAGTTACTGGGCGTAAAGGGTGTGTAGGCGGTTGTTTAAGTTTG 
GTGTGAAATCTCCCGGCTCAACTGGGAGGGTGCGCCGAATACTGAGCGAC 
TAGAGTGCGGGAGAGGAAAGTGGAATTCCTGGTGTAGCGGTGAAATGCGT 
AGATATCAGGAGGAACACCGGTGGTGTAGACGGCTTTCTGGACCGTAACT 
GACGCTGAGACACGAAAGCGTGGGTAGCAAACAGGATTAGATACCCTGGT 
AGTCCACGCCCTAAACGATGCATATTTGGTGTGGGCAGTTCATTCTGTCC 
GTGCCGGAGCTAACGCGTTAAATATGCCGCCTGGGGAGTACAGTCGCAAG 
GCTGAAACTCAAAGGAATTGACGGGGGCCCGCACAAGCGGTGGAGCATGT 
GGTTTAATTCGACGCAACGCGAAGAACCTTACCTGGGCTCGAACGGCTTC 
CCAACGCCGGTAGAAATATCGGTACCCCGCAAGGGGGTGGAATCGAGGTG 
CTGCATGGCTGTCGTCAGCTCGTGTCGTGAGATGTTGGGTTAAGTCCCGC 
AACGAGCGCAACCCTTGTCCTGTGTTGCCATGCCGCAAGGCGGCACTCGC 
AGGAGACCGCCAGCGATAAGCTGGAGGAAGGTGGGGATGACGTCAAGTCC 
TCATGGCCTTTATGTCCAGGGCTACACACGTGCTACAATGGCCGGTACAA 
AGCGTCGCTAACCTGCGAAGGGGAGCCAATCGCAAAAAACCGGTCTCAGT 
TCGGATTGCAGGCTGCAACCCGCCTGCATGAAGCTGGAATCGCTAGTAAT 
GGCAGATCAGCACGCTGCCGTGAATACGTTCCCGGGCCTTGTACACACAT 

/******************************** 
Based on code by: 
Lorenzo Seidenari ([email protected]) 
*********************************/ 

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <ctype.h> 

#define MAX_SEQUENCE_LENGTH 100000 

int n; 
int m; 
int levenshtein_distance(char *s,char*t); 
int minimum(int a,int b,int c); 

//----------------------------------------------------------------------------- 
void cleanString(char string[]) { 
    //Removes all spaces from string pointed to by "string", converts characters 
    //to uppercase, and deletes a terminating newline character. 
    int i, current; 
    int length = strlen(string); 

    current = 0; 
    for(i=0;i<length;i++) { 
     if(string[i]=='\n') { 
      string[current++] = '\0'; 
      break; 
     } 
     else if(string[i]!=' ') { 
      string[current++] = toupper(string[i]); 
     } 
    } 
} 
//----------------------------------------------------------------------------- 
int importFASTA(char *filename, char *sequence) { 
    //Reads a file, located at path specified by "filename", containing a FASTA 
    //sequence. It finds the first full, complete sequence in the file, stores 
    //it in "sequence", and returns the length of the sequence, or -1 on failure. 
    FILE *fastaFile; 
    char input[256]; 
    int readFlag; //set to 1 once a sequence has been read in 
    int length; 

    //open the file 
    if((fastaFile = fopen(filename, "r")) == NULL) { 
    return -1; 
    } 

    sequence[0] = '\0'; 

    //read the full first sequence, discarding unnecessary headers 
    readFlag=0; 
    length = 0; 
    while(fgets(input,256,fastaFile)!=NULL) { 
    //is it a header or a comment? 
    if(input[0]=='>' || input[0]==';') { 
     if(readFlag) break; 
     else continue; 
    } 
    else readFlag = 1; 

    cleanString(input); 
    length += strlen(input); 

    strncat(sequence,input,MAX_SEQUENCE_LENGTH-length - 1); 
    } 
    //Add a terminatng null character, just in case 
    sequence[length] = '\0'; 

    fclose(fastaFile); 
    return length; 
} 


/****************************************/ 
/*Implementation of Levenshtein distance*/ 
/****************************************/ 

__global__ void levenshtein_distance(char *s,char*t, int one, int two) 
/*Compute levenshtein distance between s and t*/ 
{ 
    //Step 1 
    int k,i,j,cost,*d; 
    int distance = 0; 
    if(one!=0&&two!=0) 
    { 
     d=(int *)malloc((sizeof(int))*(two+1)*(one+1)); 
     two++; 
     one++; 
     //Step 2  
     for(k=0;k<one;k++){ 
      d[k]=k; 
     } 
     for(k=0;k<two;k++){ 
      d[k*one]=k; 
     } 
     //Step 3 and 4 
     for(i=1;i<one;i++){ 
      for(j=1;j<two;j++) 
      { 
       //Step 5 
       printf("%d %d %d\n", one, i, j); 
       if(s[i-1]==t[j-1]){ 
        cost=0; 
        printf("%d %d %d\n", one, i, j); 
       } 
       else{ 
        cost=1; 
        printf("%d %d %d\n", one, i, j); 
       } 
       printf("%d %d %d\n", one, i, j); 
       //Step 6 
       int min = d[(j-1)*one+i]+1; 
       if (d[j*one+i-1]+1 < min) 
        min = d[j*one+i-1]+1; 
       if (d[(j-1)*one+i-1]+cost < min) 
        min = d[(j-1)*one+i-1]+cost; 
       d[j*one+i] = min;   
      } 
      distance=d[one*two-1]; 
      free(d); 
      printf("%d\n", distance); 
     } 
    } 
     else 
      printf ("-1"); 
} 

int main(int argc, char *argv[]) { 
    char A[MAX_SEQUENCE_LENGTH+1]; 
    char B[MAX_SEQUENCE_LENGTH+1]; 

    if(argc < 3) { 
     printf("Usage: new_edit_distance <sequence1> <sequence2>\n"); 
     printf("<sequence1>: file containing the first sequence, FASTA format\n"); 
     printf("<sequence2>: file containing the second sequence, FASTA format\n"); 
     return EXIT_FAILURE; 
    } 

    n = importFASTA(argv[1],A); 
    m = importFASTA(argv[2],B); 

    levenshtein_distance<<<1, 1>>>(A,B, n, m); 
    cudaDeviceSynchronize(); 
    printf ("%s\n", cudaGetErrorString(cudaGetLastError())); 

    return EXIT_SUCCESS; 
} 
+0

Не могли бы вы исправить код, который имеет отношение к вашему вопросу? –

+0

они ничего не возвращают :-( –

+1

anon, несмотря на запрос @ScottHunter, мы не хотим заменять [MCVE] (http://stackoverflow.com/help/mcve) небольшим фрагментом. Вероятно, я надеюсь, что Скотт попросил более сконденсированный MCVE. У меня почти всегда был MCVE, чем фрагмент. И SO [явно также спрашивает об этом] (http://stackoverflow.com/help/on- тема). Я предлагаю, как минимум, отменить свое редактирование, а затем, если возможно, сконденсировать MCVE. –

ответ

1

Я получаю его сейчас. Вы взяли прямой серийный код C/C++, сбросили его в ядро, предназначенное для запуска этого ядра как один поток, а затем хотите перейти оттуда.

Идея правдоподобна, но вам не хватает ключевого факта о CUDA и графических процессорах: они не могут напрямую обращаться к памяти хоста.

Итак, когда вы настраиваете А и В, как это:

char A[MAX_SEQUENCE_LENGTH+1]; 
char B[MAX_SEQUENCE_LENGTH+1]; 
.... 
n = importFASTA(argv[1],A); 
m = importFASTA(argv[2],B); 

те обычные переменные, которые живут в памяти хоста. Код GPU (обычный CUDA) не может напрямую обращаться к памяти хоста. Поэтому, когда вы передаете эти указатели на ядро, как это:

levenshtein_distance<<<1, 1>>>(A,B, n, m); 

код GPU будет пытаться разыменовать эти A и B указатели и выдаст ошибку (неопределенный провал запуска).

программа Каждый CUDA имеет следующую основную последовательность:

  1. копирования данных на GPU
  2. выполнения вычислений на GPU
  3. результаты копирования назад

Вы пытались сделать шаг 2 без шага 1. Это не сработает.

Поскольку я не могу запустить вашу программу, так как у меня нет допустимых входных файлов, я сделаю следующее предложение. Я предполагаю, что вы мало что знаете о CUDA. Попробуйте добавить строки, как это:

n = importFASTA(argv[1],A);    // no change 
m = importFASTA(argv[2],B);    // no change 

char *d_A, *d_B;       // add this line 
cudaMalloc(&d_A, MAX_SEQUENCE_LENGTH+1); // add this line 
cudaMalloc(&d_B, MAX_SEQUENCE_LENGTH+1); // add this line 

cudaMemcpy(d_A, A, MAX_SEQUENCE_LENGTH+1, cudaMemcpyHostToDevice); // add 
cudaMemcpy(d_B, B, MAX_SEQUENCE_LENGTH+1, cudaMemcpyHostToDevice); // add 

levenshtein_distance<<<1, 1>>>(d_A,d_B, n, m); //modify parameters 

н и м не должны быть обработаны по-другому, поскольку вы передаете то значением.

И добавьте proper cuda error checking в свой код.

EDIT: после некоторого дальнейшего анализа, стало ясно, что эта последовательность не является правильным:

 distance=d[one*two-1]; 
     free(d); 
     printf("%d\n", distance); 
    } 
} 

Вы освободив d на каждой итерации цикла i. Это не может быть правильным. Я предлагаю вам вернуться к квадрату и сначала запустить серийный код в обычном серийном коде C, прежде чем отбросить его в ядро ​​cuda.Если вы переместите этот оператор free за пределы цикла i, ваше ядро ​​работает очень долго. Следует иметь в виду, что в ядре printf ограничен объем вывода, который можно легко сгенерировать.

Я больше не буду отлаживать ваш код для вас. Сначала загрузите свой серийный код, затем определите способ создания ядра без массового количества распечатки.

Последний комментарий: Я сказал выше, что ваш подход «правдоподобен». Это означает, что это может быть сделано для работы, то есть привести к тому же поведению, что и тот же код, выполняемый на хосте. Это не означает, что он будет работать быстро. Это не то, как вы получаете ускорение из графического процессора (запустив один блок из одного потока). Я предполагаю, что вы уже знаете это на основе своего комментария «как решить эту конкретную проблему, прежде чем запускать задачу генерации параллельного кода». Но я думаю, что отказ от ответственности в любом случае уместен.

+0

Спасибо, что h очень много! Тем не менее, я только встаю на «2» в переменной «i», поэтому кажется, что недостаточно памяти выделяется –

+0

Да, в вашем коде есть дополнительная проблема, связанная с переменной 'd' в ядро, к которому обращаются вне пределов. –

+0

Эта строка в коде ядра неверно расположена: 'free (d);' Вы освобождаете ее на каждой итерации цикла 'i'. Это не то, что вы хотите, и код, который вы сняли с этого, также не может быть правильным. –

Смежные вопросы