如果阻塞在//第5步的正下方,则问题是代码不会进入或在给定的if块之后。在开始生成并行代码的任务之前,我需要弄清楚如何解决这个特定的问题。如果您运行代码,您将看到一个print语句,指示" one"另外两个用于"我"和" j"。 if块开始后,没有其他打印语句被命中。结果我很困惑,我知道这是一个特定的问题,但是,我似乎无法确定它的原因。
任何帮助表示赞赏! 提前谢谢!
输入文件样本。
>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 (sixmoney@virgilio.it)
*********************************/
#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 :(得分:1)
我现在明白了。你直接使用串行C / C ++代码,将其放入内核,打算将该内核作为单个线程运行,然后从那里开始。
这个想法似乎有道理,但是您错过了关于CUDA和GPU的关键事实:他们无法直接访问主机内存。
所以当你像这样设置A和B时:
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步的情况下执行第2步。它无法正常工作。
由于我没有有效的输入文件,因为我无法运行您的程序,所以我会提出以下建议。我假设你对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
n并且不需要以任何不同的方式处理,因为您按价值传递了它们。
并在代码中添加proper cuda error checking。
编辑:经过一些进一步的分析,很清楚这个序列是不正确的:
distance=d[one*two-1];
free(d);
printf("%d\n", distance);
}
}
您在d
循环的每次迭代中释放i
。这不可能是正确的。我建议你回到原点,先用普通的串行C代码让你的串口代码工作,然后再将它放入cuda内核。如果将free
语句移到i
循环之外,则内核会运行很长时间。请注意,内核printf
在容易生成的输出量方面受到限制。
我不打算再为您调试代码。让你的序列代码先工作,然后找到一种方法来创建一个没有大量打印输出的内核。
最后的评论:我上面说过你的方法是合理的&#34;。这意味着它可以工作,即产生与在主机上执行的相同代码相同的行为。 不意味着它会快速运行。这不是你如何从GPU中获得加速(运行单个线程的单个块)。我假设您已经根据您的评论了解了这一点&#34;如何在开始生成并行代码的任务之前解决此特定问题。&#34;但我认为免责声明无论如何都是合适的。