Question

i try to write the data from the memory to a file. And read it back in and write it back to the memory. At the moment I have the following code for that. But as far as i can see it doesnt work fully. The data in the memory is a image. As long as i dont read it in from a file its fine. But as soon as i read it in its gets corrupted.

        size_t memsize = frameWidth * frameHeight;                      //calculate the memory size
    //Writing characters to file
    char test;

    char* data = (char*) malloc (memsize);                          //create a datablock for the data on the heap
    //*

    cudaMemcpy( data, input, memsize,cudaMemcpyDeviceToHost);       //copy the data form the cuda to the CPU
    FILE *fp;
    fp = fopen (filename, "wb");
    int frames = memsize/sizeof(char);
    for (int i = 0; i<(frames); i++)
    {
            test = data[i];
            fprintf(fp, "%c",test);
    }
    fclose (fp);
    /**/
    free(data);                                                     //clear the allocated memory

//////////////////////////////////////
//write back to the memory///////////
////////////////////////////////////
    data = (char*) malloc (memsize);                            //create a datablock for the data on the heap
    //*

//  FILE *fp;
    fp = fopen (filename, "rb"); //read


    for(int i=0; i<memsize; i++)
       fscanf(fp, "%c ", (data+i));

    cudaMemcpy( input, data, memsize,cudaMemcpyHostToDevice);       //copy the data form the cuda to the CPU
    log_kernel<<<grid, block>>>(input, pitchIn/sizeof(float), output, pitchOut/sizeof(float), frameHeight);

    fclose (fp);
    /**/
    free(data);

                                                    //clear the allocated memory

but this doesnt fully work. I see that the data gets corrupted but i cant see why can someone see the mistake I made.

Was it helpful?

Solution

Try to use

fread(data, sizeof(char), memsize, fp);

instead of

for(int i=0; i<memsize; i++) fscanf(fp, "%c ", (data+i));

May fix your problem and will be much faster. Also, fscanf and fprintf are designed to read/write formatted data, not binary fields.

OTHER TIPS

Assuming the data is actually binary and not characters, some of it can easily have value 32 or 10 or some such. You're reading the file using "%c ", which means such values (ASCII code of space and linefeed, respectively) will happily be skipped as whitespace.

Seeing as you've tagged this with C++, you could simply do I/O the C++ way:

cudaMemcpy( data, input, memsize,cudaMemcpyDeviceToHost);
{
  std::ofstream f(filename, std::ios::binary);
  f.write(data, memsize);
}
free(data);

// And

{
  std::ifstream f(filename, std::ios::binary);
  f.read(data, memsize);
}
cudaMemcpy( input, data, memsize,cudaMemcpyHostToDevice);

Of course, you could also use std::vector<char> instead of char* and get rid of all the manual allocation and deallocation. The code would then simplify:

size_t memsize = frameWidth * frameHeight;
std::vector<char> data(memsize);
cudaMemcpy(&data[0], input, memsize,cudaMemcpyDeviceToHost);
{
  std::ofstream f(filename, std::ios::binary);
  f.write(&data[00, memsize);
}
data.clear();

// Now read back

data.resize(memsize);
{
  std::ifstream f(filename, std::ios::binary);
  f.read(&data[0], memsize);
}
cudaMemcpy( input, data, memsize,cudaMemcpyHostToDevice);

data.clear(); // optionally
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top