[parsec-users] which program supports solaris/sparc ?

Kshitij Sudan kshitij at cs.utah.edu
Sat Apr 12 20:40:24 EDT 2008


Hi Christian,

I tried your suggestions but there's a slight problem with the code
you sent. The problem arises while converting a little-endian, 32-bit
floating point number read from the binary file on SPARC.

The routines you wrote for swapping 32-bit numbers is somehow messing
up correct value of float because when the variable
"restParticlesPerMeter" is read and converted on SPARC it gives the
following value:
restParticlesPerMeter= 0.000000

however, when this is read on x86, it gives this value>>
restParticlesPerMeter= 392.000000

The conversion for 32-bit integers works and the variable
"numParticles" is correctly read and swapped on the SPARC m/c.

Any pointers for porting floating point numbers?

-Kshitij

This is a scrub program I wrote from your functions and fluidanimate
code for testing>>
-----------------------------------------------------------------
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<assert.h>

typedef uint8_t BYTE;
typedef uint16_t WORD;
typedef uint32_t DWORD;
typedef int32_t LONG;

bool isLittleEndian() {
  union {
    WORD word;
    BYTE byte;
  }endian_test;
  endian_test.word = 0x00FF;
  return (endian_test.byte == 0xFF);
}

//Invert the byte order of a 16-bit word
WORD swap_16(WORD x) {
  union {
    WORD x_16;
    BYTE x_8[2];
  } mem_array;
  BYTE temp;

  mem_array.x_16 = x;
  temp = mem_array.x_8[0];
  mem_array.x_8[0] = mem_array.x_8[1];
  mem_array.x_8[1] = temp;

  return mem_array.x_16;
}

//Invert the byte order of a 32-bit word
DWORD swap_32(DWORD x) {
  union {
    DWORD x_32;
    WORD x_16[2];
    BYTE x_8[4];
  } mem_array;
  BYTE temp;

  mem_array.x_32 = x;
  //swap outer bytes
  temp = mem_array.x_8[0];
  mem_array.x_8[0] = mem_array.x_8[3];
  mem_array.x_8[3] = temp;
  //swap inner bytes
  temp = mem_array.x_8[1];
  mem_array.x_8[1] = mem_array.x_8[2];
  mem_array.x_8[2] = temp;

  return mem_array.x_32;
}

int main(void)
{
  float restParticlesPerMeter;
  int origNumParticles, numParticles;

  std::ifstream file("in_35K.fluid", std::ios::binary);
  assert(file);

  file.read((char *)&restParticlesPerMeter, 4);
  file.read((char *)&origNumParticles, 4);
	
  if(!isLittleEndian()) {
    printf("flipping bytes for SPARC!\n");
    restParticlesPerMeter = swap_32(restParticlesPerMeter);
    origNumParticles = swap_32(origNumParticles);
  }

  numParticles = origNumParticles;
  printf("numParticles= %d\n",numParticles);
  printf("restParticlesPerMeter= %f\n",restParticlesPerMeter);
  return 0;
}


On Thu, Apr 15, 2004 at 10:51 PM, Christian Bienia
<cbienia at cs.princeton.edu> wrote:
> Hi Kshitij,
>
>  You made a good observation. Fluidanimate loads its input data from a
>  file which is in binary format. In order to use the program it is
>  necessary to flip all loaded variables larger than 1 byte. That's not
>  difficult to do, I've already done that for bodytrack but haven't had
>  the time to fix the other programs. You can use the routines I wrote for
>  bodytrack in file FlexIO.cpp to get it to run correctly. Here they are:
>
>  //Detect endianness of this machine
>  bool isLittleEndian() {
>   union {
>     WORD word;
>     BYTE byte;
>   } endian_test;
>
>   endian_test.word = 0x00FF;
>   return (endian_test.byte == 0xFF);
>  }
>
>  //Invert the byte order of a 16-bit word
>  WORD swap_16(WORD x) {
>   union {
>     WORD x_16;
>     BYTE x_8[2];
>   } mem_array;
>   BYTE temp;
>
>   mem_array.x_16 = x;
>   temp = mem_array.x_8[0];
>   mem_array.x_8[0] = mem_array.x_8[1];
>   mem_array.x_8[1] = temp;
>
>   return mem_array.x_16;
>  }
>
>  //Invert the byte order of a 32-bit word
>  DWORD swap_32(DWORD x) {
>   union {
>     DWORD x_32;
>     WORD x_16[2];
>     BYTE x_8[4];
>   } mem_array;
>   BYTE temp;
>
>   mem_array.x_32 = x;
>   //swap outer bytes
>   temp = mem_array.x_8[0];
>   mem_array.x_8[0] = mem_array.x_8[3];
>   mem_array.x_8[3] = temp;
>   //swap inner bytes
>   temp = mem_array.x_8[1];
>   mem_array.x_8[1] = mem_array.x_8[2];
>   mem_array.x_8[2] = temp;
>
>   return mem_array.x_32;
>  }
>
>
>
>  You would use them as follows after you've loaded a value into a
>  variable (example also taken from FlexIO.cpp):
>
>
>  if(!isLittleEndian()) {
>   bmfh->bfType = swap_16(bmfh->bfType);
>   bmfh->bfSize = swap_32(bmfh->bfSize);
>   bmfh->bfReserved1 = swap_16(bmfh->bfReserved1);
>   bmfh->bfReserved2 = swap_16(bmfh->bfReserved2);
>   bmfh->bfOffBits = swap_32(bmfh->bfOffBits);
>  }
>
>
>  Fluidanimate uses the file.read method to load data from file. I counted
>  11 occurrences. Simply convert it as follows as shown below. The code...
>
>  file.read((char *)&restParticlesPerMeter, 4);
>  file.read((char *)&origNumParticles, 4);
>
>  ...would become...
>
>  file.read((char *)&restParticlesPerMeter, 4);
>  file.read((char *)&origNumParticles, 4);
>  if(!isLittleEndian()) {
>   restParticlesPerMeter = swap_32(restParticlesPerMeter);
>   origNumParticles = swap_32(origNumParticles);
>  }
>
>  Do the same where it reads the particles a little farther down and it
>  should work. If you get something to work please post a patch to this
>  mailing list.
>
>  - Chris
>


More information about the parsec-users mailing list