Hello everybody I'm with problems to make my program work with GSL - root finding. I'm trying find a solution to my equation. I'm looking solutions for a data with 64 lines, but in some specific lines the program can't continue, maybe because a good solution is not existent. But I want that the program just skip line when he don't find a solution. But my program just stop sometimes and appear this message:
gsl: brent.c:74: ERROR: endpoints do not straddle y=0
passou1passou2passou3Default GSL error handler invoked.
Abort trap: 6
So, I did some prints to check where exactly my program stop and I found that is in gsl_root_fsolver_set(s,&F, x_lo, x_hi), but I didn't find how print this value or what this function give to me.
My program is here, thanks everybody!
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_complex_math.h>
#include <gsl/gsl_roots.h>
#include "demo_fn.h"
#include "demo_fn.c"
int
main (void)
{
double NT, c;
c = 64.0/2.0;
char url[]="charm.txt";
double corr, core, a[64][3];
int nt, i = 0;
FILE *arq;
arq = fopen(url, "r");
if(arq == NULL)
printf("Erro, nao foi possivel abrir o arquivo\n");
else
while( (fscanf(arq,"%lf %lf %i\n", &corr, &core, &nt))!=EOF ) {
a[i][0]=corr;
a[i][1]=core;
a[i][2]=nt;
i++;
//printf("%lf, %lf, %i\n",corr, core, nt);
}
fclose(arq);
for (i= 0; i < 64; i++)
{
int status;
int iter = 0, max_iter = 200;
const gsl_root_fsolver_type *T;
gsl_root_fsolver *s;
double r = 0, r_expected = 4.0;
double x_lo = 0.0001, x_hi = 4.0;
double ratio1, ratio2;
ratio1 = a[i][0]/a[i+1][0];
ratio2 = a[i+1][0]/a[i+2][0];
printf ("ratio1: %lf, ratio2: %lf", ratio1, ratio2);
printf ("\n");
// if (ratio1*ratio2 > 0)
// {
printf("C(n_t) : %.15lf -- loop index : %i ----- ratio: %lf \n", a[i][0],i, ratio1);
gsl_function F;
struct quadratic_params params = {a[i][0], i, c, i+1, a[i+1][0]};
F.function = &quadratic;
printf ("passou1");
F.params = ¶ms;
T = gsl_root_fsolver_brent;
printf ("passou2");
//T = gsl_root_fsolver_bisection;
s = gsl_root_fsolver_alloc (T);
printf ("passou3");
gsl_root_fsolver_set (s, &F, x_lo, x_hi);
printf ("passou4");
printf ("using %s method\n", gsl_root_fsolver_name (s));
printf ("%5s [%9s, %9s] %9s %10s %9s\n", "iter", "lower", "upper", "root", "err", "err(est)");
do
{
iter++;
status = gsl_root_fsolver_iterate (s);
r = gsl_root_fsolver_root (s);
x_lo = gsl_root_fsolver_x_lower (s);
x_hi = gsl_root_fsolver_x_upper (s);
status = gsl_root_test_interval (x_lo, x_hi,0, 0.001);
if (status == GSL_SUCCESS)
{
printf ("Converged:\n");
}
printf ("%5d [%.7lf, %.7lf] %.7lf %+.7lf %.7lf\n", iter, x_lo, x_hi, r, r - r_expected, x_hi - x_lo);
}
while (status == GSL_CONTINUE && iter < max_iter);
gsl_root_fsolver_free (s);
// }
printf("\n");
}
return 0;
}
Gabriela. The output has already told you why you program is wrong. Endpoints do not straddle y=0.
The root bracketing algorithms described in this section require an initial interval which is guaranteed to contain a root—if a and b are the endpoints of the interval then f(a) must differ in sign from f(b).
The above is from the manual of gsl, so if the end points have the same sign, the program will stop and tell you this error.
Have you ever tried the error handler in gsl. In the chapter 3 of the manual, they offer a function called gsl_set_error_handler_off(), if you place this function just before gsl_root_fsolver_set(s,&F, x_lo, x_hi), and you can assign this function to an int type variable, let's say status, as we can see from the manual that it(gsl_root_fsolver_set(s,&F, x_lo, x_hi)) is an int function, then if you print out the value of status, and check it with gsl_errno.h file, you will know what that value mean.
This gsl_set_error_handler_off() can dismiss the abortion from execution.
as for you code, you should do the following:
add #include <gsl/gsl_errno.h>
add gsl_set_error_handler_off() before status=gsl_root_fsolver_set(s,&F, x_lo, x_hi)
use the value of status like the following loop of you program to make little changes of you end points,to expand or narrow or translate your interval, when they satisfied the initial condition, the program will run again
Related
I'm working on a C program to manipulate large volumes of CSV data. It was running fine in develoment with a smallish test file. But when the size of the file increases, it starts to fail. Depending on whether I compile it with gcc or minGW's gcc, it fails with segmentation error or 3221225477 / 0xC0000005 at different places, always either :
if (fclose(fp)) {
printf("Error closing file: %s, %s, %d.\n", fileName, __func__, __LINE__);
exit(300);
}
Note it doesn't get past the fclose(). Or one of these:
data_PE_T12 = calloc(width_T*dataDepthDay, sizeof(*data_PE_T12));
It's long, so I'll try to show the relevant parts. First the Main function:
#include <stdio.h>
#include <string.h> // strtok
#include <stdlib.h> // atoi & atof
#include <time.h> // time functions
#include <math.h> // expf()
...
// Array Sizes
static int dataDepth, dataDepthDay;
static int fromTime, toTime;
static int width, width_T, width_H, width_C;
// Array Pointers
static int *timeArray, *timeArrayDay, *timeArrayPE;
static struct sensorHeader_t *headerArray, *headerArray_T, *headerArray_H, *headerArray_C;
// of depth dataDepthDay
static float *data_E_T25, *data_E_T30;
static float *data_E_T12, *data_E_T18, *data_E_H60, *data_E_H70, *data_E_C1500;
static float *data_PE_T12, *data_PE_T18, *data_PE_H60, *data_PE_H70, *data_PE_C1500;
... plus loads more.
// functions
void grabDepth(void); // OK
void grabPayload(void); // OK
... plus loads more.
int main(int argc, char **argv)
{
// Grab Input File Name
if (argc == 2) {
strcpy(rawFile, "in/");
strcat(rawFile, argv[1]);
} else { // dev
strcpy(rawFile, "in/sensor_report.csv");
}
printf("size max = %d", __SIZE_MAX__);
// Parse and Copy File
grabDepth();
grabPayload();
// Run functions
genRawData(); // Raw T, H & C files
genExposureE(); //
genExposureAPE(); //
return 0;
}
Next the first function that is called. This one opens the main input file and pulls out a number of array widths and depths that are used to calloc for arrays already declared as static pointers. The idea is that this will make the memory handling nice and flexible as the file size increases...
void grabDepth(void)
{
// 1. Open File
FILE *fp = fopen(rawFile, "r");
char buf[15000]; // Big enough to deal with lots of devices.
if (!fp) {
printf("Can't open the file: %s: %s, %d.\n", rawFile, __func__, __LINE__);
exit(100);
}
while (fgets (buf, sizeof(buf), fp)) {
int lineLen = strlen(buf);
int colNum = 1;
char *field = strtok(buf, ",");
if (field && strcmp(field, "From") == 0) {
// printf("\n\n*** row 2 ***\n\n");
// int fromTime, toTime = 0;
while (field) {
if (colNum == 2) {
fromTime = atof(field);
}
if (colNum == 4) {
toTime = atof(field);
}
field = strtok(NULL, ",");
colNum++;
}
// printf("FromTime = %d. ToTime = %d.\n", fromTime, toTime);
dataDepth = ( toTime - fromTime )/900;
// printf("dataDepth = %d.\n", dataDepth);
continue; // to next iteration.
}
// 3. Grab file width from line 10 (commsType) Check if buf Overruns too
if (field && strcmp(field, "TimeStamp") == 0) {
// First Check Line is long enough!
if (lineLen == sizeof(buf)-1) { // buf has overrun!
printf("File Read-Line Overrun: %s, %d.\n", rawFile, __func__, __LINE__);
exit(200);
}
// printf("Line Length = %d\n", lineLen);
// printf("Buf Size = %d\n", sizeof(buf));
width = -2; // ignore timestamps : I ballsed up the commas in csv file (-2 instead of -1)
while (field) {
if(field = strtok(NULL, ",")) {
width ++;
}
}
break; // out of loop!
}
}
//dataDepthDay = dataDepth/96 + (dataDepth % 96 !=0); // round up?!
dataDepthDay = dataDepth/96; // round down?!
printf("\n 1. grabDepth() Results\n");
printf( "------------------------\n");
printf("Raw Data Width = %d\n", width);
printf("Raw Data Depth = %d\n", dataDepth);
printf("dataDepthDay Depth = %d\n\n", dataDepthDay);
if (fclose(fp)) {
printf("Error closing file: %s, %d.\n", rawFile, __func__, __LINE__);
exit(300);
}
}
After that, it's just calling one function after another, all of which follow the general pattern of:
void _genRawData(char* sensorType, struct sensorHeader_t *sensorHeader, float *dataArray, int *timeArray, size_t dataDepth, size_t width) {
FILE *fp;
strcpy(fileName, "out/");
strcat(fileName, sensorType);
strcat(fileName, "_raw.csv");
fp = fopen(fileName, "w");
// check file opened OK.
if (fp == NULL) {
printf("Error! Couldn't Create file: %s\n", fileName);
return;
}
printf("building file : %s\n", fileName);
// Allocate Memory
timeArrayDay = calloc(dataDepthDay, sizeof(*timeArrayDay));
timeArrayPE = calloc(dataDepthDay, sizeof(*timeArrayPE)); // xxxx same array as day time array!?
data_E_T12 = calloc(width_T*dataDepthDay, sizeof(*data_E_T12));
data_E_T18 = calloc(width_T*dataDepthDay, sizeof(*data_E_T18));
data_E_H60 = calloc(width_H*dataDepthDay, sizeof(*data_E_H60));
data_E_H70 = calloc(width_H*dataDepthDay, sizeof(*data_E_H70));
// do stuff and build new arrays up and put into files...
if (fclose(fp)) {
printf("Error closing file: %s, %d.\n", rawFile, __func__, __LINE__);
exit(300);
}
}
I've only called calloc once on each 2-D array, and for the sake of debugging I've removed the free() calls.
I figure I'm doing something wrong with memory management, which is biting me when the array sizes grow past a certain point, but I can't figure out what's wrong. I've tried to make sure the memory I access has been allocated correctly and working on a big powerful actual computer (I'm an embedded person usually), I wouldn't expect any issues with OS handing out data? Isn't there plenty to go around!?
In case the outcome is of use to others. I suspected there was an issue with the calloc and subsequent use of the allocated memory. So I tried 2 things:
1: Checked the memory usage in the code:
// Add Values & Write Line on new Day & Reset Accumulator
for (i=0; i < dataDepth; i++) {
for (j=0; j < width; j++) {
if (newDay) {
fprintf(fp, ",%.2f", APE_Accum[j]);
data_E_Array[(data_E_Index-1)*width+j] = APE_Accum[j];
if ((data_E_Index-1)*width+j+1 > (width_T*dataDepthDay)) {
printf("Oh bugger...\n");
printf("width_T*dataDepthDay = %d\n", width_T*dataDepthDay);
printf("data_E_Index-1 = %d\n", data_E_Index-1);
printf("width = %d\n", width);
printf("dataDepthDay = %d\n", dataDepthDay);
printf("width_T = %d\n", width_T);
printf("j = %d\n\n", j);
Really messy code, so you can understand how I lost track of the array bounds. Basically, it became obvious that I'd messed up my calculation of the size of the calloc. I was possible to find the problem like this, but I don't think it's a vaiable answer to my question, since it would scale to large or even more convoluted code.
2: Valgrind. Following #dbush s advice. I moved over to Ubuntu, installed Valgrind, and recompiled...
$ sudo apt install valgrind
$ ps aux | grep-i apt
$ gcc -o graphomatic ./graphomatic.c -lm -g
$ valgrind --leak-check=full --show-leak-kinds=all --verbose --track-origins=yes --log-file=valgrind-log
$ less valgrind-log
And Bob's your uncle. The problems jumped right out. I needed to add the -lm to link to the math library. And teh -g to make sure line numbers were included in the Valgrind output.
==15878== Invalid write of size 4
==15878== at 0x4038EA: _genExposureE (graphomatic.c:867)
==15878== by 0x404A0C: genExposureE (graphomatic.c:1235)
==15878== by 0x400EAA: main (graphomatic.c:122)
==15878== Address 0x75cd604 is 0 bytes after a block of size 660 alloc'd
==15878== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15878== by 0x404911: genExposureE (graphomatic.c:1222)
==15878== by 0x400EAA: main (graphomatic.c:122)
The code=3221225477 in terminal/shell.
This error/exception is thrown at times when you have segmentation errors.
By segmentation error, I mean that either you are trying to access a memory not allocated in an array.
Example:
vector<int> arr={1,2,3,4,5,6,7,8,9};
cout<<arr.at(arr.size());
This error code can also be shown as out of bound error, out of range error, or segmentation error, etc.
I am trying to compile my code and this error is popping up:
#include <stdio.h>
//Prototype
int scan_fraction(int *nump, int *denomp);
//Execution
int main ()
{
int nump, denomp;
scan_fraction(&nump, &denomp);
}
//Definition
void scan_fraction(int *nump, int *denomp)
{
char slash; /* character between numerator and denominator */
int status; /* status code returned by scanf indicating
number of valid values obtained */
int error; /* flag indicating presence of an error */
char discard; /* unprocessed character from input line */
do {
/* No errors detected yet */
error = 0;
/* Get a fraction from the user */
printf("Enter a common fraction as two integers separated ");
printf("by a slash> ");
status = scanf("%d %c%d",&nump, &slash, denomp);
/* Validate the fraction */
if (status < 3) {
error = 1;
printf("Invalid-please read directions carefully\n");
} else if (slash != '/') {
error = 1;
printf("Invalid-separate numerator and denominator");
printf(" by a slash (/)\n");
} else if (denomp <= 0) {
error = 1;
printf("Invalid—denominator must be positive\n");
}
/* Discard extra input characters */
do {
scanf("%c", &discard);
} while (discard != '\n');
} while (error);
}
What could be the error? Can somebody explain to me why it is the error. I'm still learning at C.
You declare this:
int scan_fraction(int* nump, int* denomp);
And your implementation is this:
void scan_fraction(int* nump, int* denomp)
Declaration and implementation don't match.
Also, you have:
status = scanf("%d %c%d", &nump, &slash, denomp);
You should use this, because nump is already a pointer to int:
status = scanf("%d %c%d", nump, &slash, denomp);
Your compiler should be telling you about this, too.
I'm trying to generate a tabulation file for 1000 data points using this code below, the program works when I don't add the File Creation and Opening section, but when this is added the program doesn't end once I've entered the inputs.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void mapfun(int imap, double *c, double xi, double yi, double *xo, double *yo);
void mapspin(int imap, double *c, int nspin, double *xo, double *yo);
int main(){
/* Defining values */
int imap;
int nspin=1000;
double xo;
double yo;
double c[4];
float mu;
/* Ask for an input of 1 or 2 */
printf("Input 1 or 2\n");
scanf("%d", &imap);
/* Assigning c when input is 1 and assigning mu */
if(imap==1){
c[1]=0.04;
c[2]=0.04;
printf("Input a value for mu between 2.8 and 3.8\n");
scanf("%e:%d", &mu);
if(mu>2.8 && mu<3.8){
c[0]=mu;
c[3]=mu;
} else{
printf("Invalid value for mu\n");
exit(0);
}
/* Assigning c when input is 2 and assigning mu */
} else if(imap==2){
c[1]=1;
c[2]=1;
printf("Input a value for mu between 1 and 3\n");
scanf("%e:%d", &mu);
if(mu>1 && mu<3){
c[0]=mu;
c[3]=mu;
} else{
printf("Invalid value for mu\n");
exit(0);
}
} else{
printf("Invalid value entered\n");
exit(0);
}
mapspin(imap, c, nspin, &xo, &yo);
/*File Creation and Opening*/
FILE*orbit;
orbit = fopen("orbit.dat", "rb+");
if(orbit == NULL) {
/* creates file if not there */
orbit = fopen("orbit.dat", "wb");
}
double xi=xo;
double yi=yo;
int i;
for(i=0; i<nspin; i+1){
mapfun(imap, c, xi, yi, &xo, &yo);
xi=xo;
yi=yo;
fprintf(orbit, "xo = %3f, yo = %3f\n", xo, yo);
}
orbit = fopen("orbit.dat", "r");
printf("c[0]= %.2f, c[1]= %.2f, c[2]= %.2f, c[3]= %.2f\n", c[0], c[1], c[2], c[3]);
exit(0);
}
Main problem:
The for loop is not well formed.
for(i=0; i<nspin; i+1){
^^^ This does not change the value of i
^^^ That explains why the loop never ends.
Use:
for(i=0; i<nspin; ++i){
Another issue:
I don't understand why you have the line:
orbit = fopen("orbit.dat", "r");
That seems to be an unnecessary line.
Additional Info
The following program illustrates how you can accidentally modify a value in a function called from main.
#include <stdio.h>
void foo(int* x)
{
x[1] = 20;
}
int main()
{
int a = 10;
int b;
printf("Value of a before call to foo: %d\n", a);
foo(&b); // foo has no direct access to "a" but it can
// indirectly access "b" by using an out of
// bounds index.
printf("Value of a after call to foo: %d\n", a);
}
I built the program using gcc 4.8.2. When I run the program, the output is:
Value of a before call to foo: 10
Value of a after call to foo: 20
You write ascii/text into a binary open file with the boption. I think if the file exists you just have to append by using a fopen option and ths will create the file if it doesn't exists:
orbit = fopen("orbit.dat", "a");
if(orbit == NULL) {
//IO Error cannot open the file in append mode or create the file
exit(1);
}
And don't reuse a file descriptor variable without doing fclose call:
fprintf(orbit, "xo = %3f, yo = %3f\n", xo, yo);
//Fprintf Return value must be checked too
}
if( 0 != fclose( orbit ) )
{
//IO Error cannot close the opened file
exit(1);
}
orbit = fopen("orbit.dat", "r");
if( orbit == NULL )
{
//IO Error cannot open the file for reading
exit(1);
}
Each IO call return value/errno must be checked!
And the main problem reported by #r-sahu is the for loop.
Stuck at if block right below //step 5, the issue is that the code will not progress into or after the given if block. I need to figure out how to get this particular issue settled before starting the task of generating parallel code. If you run the code you will see one print statement that indicates the value of "one" and another two for "i" and "j". After the if block begins, none of the other print statements are hit. As a result I am quite stuck, I am aware that this is a specific issue, however, I cannot seem to determine it's cause.
Any help is appreciated!
Thanks in advance!
Input file sample.
>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;
}
I get it now. You took straight serial C/C++ code, dropped it into a kernel, intended to run that kernel as a single thread, and then want to proceed from there.
The idea is plausible, but you're missing a key fact about CUDA and GPUs: they can't directly access host memory.
So when you set up A and B like this:
char A[MAX_SEQUENCE_LENGTH+1];
char B[MAX_SEQUENCE_LENGTH+1];
....
n = importFASTA(argv[1],A);
m = importFASTA(argv[2],B);
those are ordinary variables that live in host memory. GPU (ordinary CUDA) code can't directly access host memory. So when you pass those pointers to a kernel like this:
levenshtein_distance<<<1, 1>>>(A,B, n, m);
the GPU code will try and dereference those A and B pointers and will fault (unspecified launch failure).
Every CUDA program has the following basic sequence:
copy data to the GPU
perform computations on the GPU
copy results back
You've tried to do step 2 without step 1. It won't work.
Since I'm not able to run your program since I don't have valid input files, I'll make the following suggestion. I assume you know little or nothing about CUDA. Try adding lines like this:
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 and m don't need to be handled any differently since you are passing those by value.
And add proper cuda error checking to your code.
EDIT: after some further analysis, it's clear that this sequence is not correct:
distance=d[one*two-1];
free(d);
printf("%d\n", distance);
}
}
You are freeing d on every iteration of the i loop. That cannot possibly be correct. I suggest you go back to square one and get your serial code working first, in ordinary serial C code, before dropping it into a cuda kernel this way. If you move that free statement outside the i loop, then your kernel runs for a very very long time. Be advised that in-kernel printf is limited in the amount of output that can be easily generated.
I'm not going to debug your code any further for you. Get your serial code working first, then figure out a way to create a kernel without massive quantities of printout.
A final comment: I said above your approach is "plausible". That it means it could be made to work, i.e produce the same behavior as the same code executing on the host. It does not mean it will run fast. This is not how you get acceleration out of a GPU (running a single block of a single thread). I assume you already know this based on your comment "how to get this particular issue settled before starting the task of generating parallel code." But I think the disclaimer is appropriate anyway.
I am using Dev-c++ IDE to compile my C (WIN32 API) programs.
I am using regex lirary provided by http://gnuwin32.sourceforge.net/packages/regex.htm
I am using this documentation for reference and the same has been provided from the above site... http://pubs.opengroup.org/onlinepubs/009695399/functions/regcomp.html
Following is the Code:
#include <cstdlib>
#include <iostream>
#include <sys/types.h>
#include <regex.h>
#include <conio.h>
#include <stdio.h>
using namespace std;
int main(int argc, char *argv[])
{
int a;
regex_t re;
char str[128] = "onces sam lived with samle to win samile hehe sam hoho sam\0";
regmatch_t pm;
a = regcomp(&re,"sam", 0);
if(a!=0)
{
puts("Invalid Regex");
getch();
return 0;
}
a = regexec(&re, &str[0], 1, &pm, REG_EXTENDED);
printf("\n first match at %d",pm.rm_eo);
int cnt = 0;
while(a==0)
{
a = regexec(&re, &str[0] + pm.rm_eo, 1, &pm, 0);
printf("\n next match %d",pm.rm_eo);
cnt++;
if(cnt>6)break;
}
getch();
return EXIT_SUCCESS;
}
The while loop goes infinite displaying the first and second end position of the matching string and not going further.
I have used the cnt variable to check for 6 turns and then i am breaking the loop to stop the infinite run.
The Output is:
first match at 9
next match 15
next match 9
next match 15
next match 9
next match 15
What am i missing here?
Try this instead:
int cnt = 0;
int offset = 0;
a = regexec(&re, &str[0], 1, &pm, REG_EXTENDED);
while(a==0) {
printf("\n %s match at %d", offset ? "next" : "first", offset+pm.rm_so);
offset += pm.rm_eo;
cnt++;
a = regexec(&re, &str[0] + offset, 1, &pm, 0);
}
You were not actually stepping through your string, which was what caused the unending loop.
I come up with this code, giving a little improvement (more compact) of the #jxh solution, and avoiding of using extra lookup &str[0]
int cnt = 0;
int offset = 0;
while(!regexec(&re, str + offset, 1, &pm, REG_EXTENDED)) {
printf("%s match at %d\n", offset ? "next" : "first", offset+pm.rm_so);
offset += pm.rm_eo;
cnt++;
}