0

i need to find a way to load an ArrayFire array from a file, the file have the format: ix iy iz val, where ( ix, iy , iz) are the coordinates in wich the value val has to be. i open the file in the c++ way ( with getline and so ) and parse the line, get correctly the indexes ix, iy ,iz and the value, val

Before i start to iterating the file, i create my array as usual

af::array af_obj(Lx,Ly,Lz, f32);

then when i'm iterating ,i use a line like this to save the values:

af_obj( ix, iy ,iz ) = val

but the array does't save the information correctly, i mean if i do the same with a simple tridimensional array, it holds correct the information.

The information in the file is a buch of 1s and 0s, representing a 3D space where, 1 represent an air region and 0s is a solid material. ( some kind of discretization to represent a sphere, the whole point is, use this array to multiply other array(holding a velocity field) so where is solid the velocity will have a zero value )

I have tried other ways, flatten the data in a 1D array and pass it to the constructor of the array, but in the best case i recover 3 spheres insted of one ( the size of the array are : Lx = 300 , Ly=Lz=100 ) but i'm not able to do what i want. I know for sure the file contain the correct data, i generate this file from other code ( if maybe changing the format of the file could help, tell me, i can modify it)

Thanks for your reading and Answers.

EDIT:

To save the data i use this:

 std::ofstream file;
  file.open("solidRegion.dat");

  for( int iz  = 0 ; iz < this->Lz; iz++ ){
    for( int iy  = 0 ; iy < this->Ly; iy++){
      for( int ix = 0 ; ix < this->Lx ; ix++){
    file << ix << " " <<  iy << " " << iz << " " << grid[ix][iy][iz] << "\n";
      }}}
  file.close();

the 3D array grid, contain the points ( 1s and 0s ) and i know it have the correct data.

And to load the file :

std::string line;
    af::array af_obj(Lx,Ly,Lz,f32);
    while( std::getline(file_h,line ) ){

      std::stringstream linestream(line);
      int x,y,z, o;
      linestream >> x >> y >> z >> o;
      af_obj(x,y,z) = o;
      object[x][y][z] = o;
    }

the object array is a classic c++ 3D array ( dimensions Lx, Ly , Lz ) and if the data is correctly saved in this array ( object ) but not in the ArrayFire object.... and i don't know why .

Edit 2 :

I try this, using a pointer of 1D memory :

int *h_o;
h_o = new int[Lx*Ly*Lz];
int i = 0;

for ( int k = 0 ; k < Lz ; k++)
  for( int ix = 0 ; ix < Lx ; ix++)
    for( int j = 0 ; j < Ly ; j++)
      {

        h_o[i] = object[ix][j][k];
        i++;
              }
    af::array af_obj(Lx, Ly ,Lz , h_o); 

Knowing that de 3D object[][][] array, has the correct information !

but the ArrayFire object af_obj not, as i said before the array represent a sphere, in the best case the ArrayFire object show 3 spheres ( no idea why ). The order of the nested fors matters, buy i try all posible combination of xyz and nothing seems to work.

RolandDeschain
  • 483
  • 1
  • 4
  • 17
  • Maybe you should show how you're saving and loading it. – user253751 Mar 03 '16 at 20:04
  • hi @immibis , i edit the question and add the code. any hint? – RolandDeschain Mar 03 '16 at 20:33
  • 1
    ArrayFire has functions to read and write Arrays from file.They are called readArray and saveArray. The documentation is here: http://arrayfire.org/docs/group__dataio__mat.htm – shehzan Mar 03 '16 at 20:55
  • hi @shehzan But that is not what i'm looking for. I need to load the .txt generated by other programm in my ArrayFire array... – RolandDeschain Mar 03 '16 at 21:15
  • Then your only option is to do it by reading it on host first and the to ArrayFire. The second part of your code has `af_obj(x,y,z) = o`. This is not ideal for ArrayFire. You are better off reading the entire array into memory as an array and then call the array constructor as `array af_obj(Lx, Ly, Lz, myPtr, type)`. This assumes that your memory is continuous starting at myPtr. – shehzan Mar 03 '16 at 22:01
  • I try that, but for some reason not work. I think is the order of the fors ( i read it in a 3D array and then try to flat this data in a 1D array, but i'm not sure how this flatten process have to be done, so the ArrayFire constructor recovers exactly the 3D array .... i think the key is in understanding the dimensions and how ArrayFire Take the 1D data and construct the array object... – RolandDeschain Mar 03 '16 at 22:31
  • Are you sure that your memory is contiguous? You have not shown anything about how you are allocating your 3D host memory, so I cannot give a definite answer to why it may not be working. ArrayFire requires you to have contiguous memory since the memory on device, although represented as N-dimensional, is really a flat memory buffer. – shehzan Mar 04 '16 at 15:02
  • hi @shehzan , i edited the question, showing the code in which i use a flat memory to construct the array – RolandDeschain Mar 04 '16 at 17:41
  • I'm not really sure what you mean by "represents a sphere" and "shows 3 spheres". Is `Lz` =3? When you create an array of `Lx` * `Ly` * `Lz`, you are creating an array with `Lx` rows, `Ly` cols and `Lz` channels/matrices. The code you added should work just fine and create the array. So when you do af_print(af_obj), it should print `Lz` number of matrices of `Lx` rows and `Ly` cols. Is your object[][][] row major or column major? – shehzan Mar 05 '16 at 20:08
  • Yes i figured it out... it was a stupid mistake in the way the information was printed. thanks for your answers :D – RolandDeschain Mar 07 '16 at 01:04

0 Answers0