The GWO library easy documantation
(written by Tomoyoshi Shimobaba @ Yamagata University, Japan)
 
In optics, several diffraction integrals, such as the angular spectrum method and the Fresnel diffractions, are used for calculating scalar light propagation.
The calculation result provides us with the optical characteristics of an optical device, the numerical reconstruction image from a hologram, and so forth.
The acceleration of the calculation commonly uses the fast Fourier transform; however, in order to analyze a three-dimensional characteristic of an optical device and compute real-time reconstruction from holograms, recent computers do not have sufficient computational power.
 
The GWO (GPU-based Wave Optics) library is numerical calculation library for the diffraction integrals using a GPU (Graphics Processing Unit). If optics engineers and researchers have no knowledge of GPU, the GWO library provides them with the GPU calculation power easily.


You can download the GWO library from http://sourceforge.net/projects/thegwolibrary/

The system requirements of the GWO library are as follows:

(1) Operating system : Windows XP
(2) NVIDIA CUDA version : 2.0 (please download here)
(3) NVIDIA GPU (Geforce8800 higher)

The installation of the GWO library is as follows:

(1) Please place the GWO files (gwo.dll, gwo.h, gwo.lib) on your project directory.
(2) Please register gwo.h and gwo.lib to your project.

If you have any problem or want to add a new function to the library,
please feel free to contact me.


Sample code using the GWO library (1)

We show a sample code in order to calculate diffraction.

#include "gwo.h"

#define WIDTH 1024
#define HEIGHT 1024
#define WIDTH2    (WIDTH*2)
#define HEIGHT2    (HEIGHT*2)

float gwo_max=0.0, gwo_min=0.0;

//gwoComplex is the complex number.
//if you use to the real part of gwoComplex, please use GWO_RE(...).
//if you use to the imaginary part of gwoComplex, please use GWO_IM(...).

gwoComplex ape_small[WIDTH*WIDTH];
gwoComplex ape[WIDTH2*HEIGHT2];
gwoComplex result[WIDTH*HEIGHT];

unsigned char pix[WIDTH*WIDTH];

void main()
{
    //Prepare an aperture with 20*20 pixel.

    for(int i=0;i<HEIGHT;i++)
    {   
        for(int j=0;j<WIDTH;j++)
        {
            if(j>WIDTH/2-10 && j<WIDTH/2+10 && >HEIGHT/2-10 && i<HEIGHT/2+10)
            {
                GWO_RE(ape_small[(j)+(i)*WIDTH])=1.0;
                GWO_IM(ape_small[(j)+(i)*WIDTH])=0.0;
            }
        }
    }

    //Initialize the library.

    gwoInit(GWO_ANGULAR,WIDTH2,HEIGHT2); //if you calculate the Angular spectrum
    //gwoInit(GWO_FRESNEL_CONV,WIDTH2,HEIGHT2);//if you calculate the Fresnel difraction(convolution type)
    //gwoInit(GWO_SHIFTED_FRESNEL,WIDTH2,HEIGHT2);////if you calculate the Shifted-Fresnel difraction

    //Expands the original aperture (ape_small).
    //The expanded aperture (ape) has double size as compared with the original aperture.

    gwoHostExpandC2C(
        ape_small,WIDTH,HEIGHT,
        ape,WIDTH2,HEIGHT2);
   
    //Set the sampling spacing (4.65 um) on the aperture and the diffracted plane.
    gwoSetPitch(4.65e-6, 4.65e-6);

    //Set the wavelength (633nm).
    gwoSetWaveLength(633.0e-9);

    //Send the expanded aperture to the GPU.
    gwoSendData(ape);

    //Calculate the diffraction with the propagation distance of 0.2m.
    gwoCalc(0.2);
   
    //If you need the light intensity of the diffracted light,
    //please execute gwoIntensity().
    //If you do not need the light intensity,
    //please comment out gwoIntensity();

    gwoIntensity();

    //The host computer receives the calculated result (the diffracted result).

    gwoReceiveResult(ape);
       
    //Reduce the expanded aperture (ape) to the buffer (result).

    gwoHostExpandC2C(
        ape,WIDTH2,HEIGHT2,
        result,WIDTH,HEIGHT);

    //Search the maximum and minimum value in the buffer (result).

    gwoHostSearchMaxMin(result,&gwo_max,&gwo_min,WIDTH,HEIGHT);

    //Convert the light intensity to 256 monochrome image.
    for(int i=0;i<HEIGHT;i++)
    {
        for(int j=0;j<WIDTH;j++)
        {
            float tmp=GWO_RE(result[j+i*WIDTH]);
            unsigned char c=(unsigned char)(255.0*(tmp-gwo_min)/gwo_max));
            pix[j+i*WIDTH]=c;
        }
    }

    //Finalize the library.
    gwoFree();
}


Sample code using the GWO library (2)

We show a sample code in order to calculate a CGH (computer-generated-hologram) from an object with 1 point .
The calclulation using the GWO library can calculate a CGH faster than a personal computer.
The GWO library adopted CGH calculation methods by the followinf references:
  1. T. Ito,  N. Masuda,  K. Yoshimura,  A. Shiraki,  T. Shimobaba, and T. Sugie, "Special-purpose computer HORN-5 for a real-time electroholography," Optics Express 13, 1923-1932 (2005) 
  2. Tomoyoshi Shimobaba, Atsushi Shiraki, Yasuyuki Ichihashi, Nobuyuki Masuda and Tomoyoshi Ito, "Interactive color electroholography using the FPGA technology and time division switching method", IEICE Electronics Express (ELEX), Vol.5, No.8, pp.271-277 (2008)
  3. Tomoyoshi Shimobaba, Sinsuke Hishinuma and Tomoyoshi Ito, "Special-Purpose Computer for Holography HORN-4 with recurrence algorithm", Computer Physics Communications., No.148/2, pp. 160-170 (2002)
  4. Tomoyoshi Shimobaba and Tomoyoshi Ito, "An efficient computational method suitable for hardware of computer-generated hologram with phase computation by addition",  Computer Physics Communications., Vol 138, pp. 44-52 (2001)
  5. Tomoyoshi Shimobaba, Nobuyuki Masuda, Takashige Sugie, Satoru Hosono, Shinobu Tsukui, Tomoyoshi Ito, "Special-Purpose Computer for Holography HORN-3 with PLD technology",  Computer Physics Communications., Vol. 130, pp. 75-82, (2000)


#include "gwo.h"

#define CGH_W 1024
#define CGH_H 1024

void main()
{
   
    int num=1;
    num=gwoAdjustObjNum(num);

    gwoObjPoint *obj=new gwoObjPoint[num];
    float *hol=new float[CGH_W*CGH_H];

    for(int i=0;i<num;i++)
    {
        if(i==0)
        {
            obj[i].x=500.0*10e-6;
            obj[i].y=0.0;
            obj[i].z=1.0;
            obj[i].a=1.0;
        }
        else{
            obj[i].x=0.0;
            obj[i].y=0.0;
            obj[i].z=1.0;
            obj[i].a=0.0;
        }

    }

    gwoInit(GWO_CGH_RECURRENCE, CGH_W,CGH_H);
    gwoSetPitch(10.0e-6, 10.0e-6);
    gwoSetWaveLength(633.0e-9);
    gwoSetObjNum(CGH_OBJ);
   
    gwoSendData((gwoObjPoint*)obj);
    gwoCalc(NULL);
    gwoThreshold(0.0);

    gwoReceiveResult(hol);
    gwoFree();
   
    delete []obj;
    delete []hol;

}