scalarslice.cu 2.29 KB
#include "scalarslice.h"

#include "rts/cuda_handle_error.h"
#include "cublas_v2.h"
#include "envi/rtsEnvi.h"

scalarslice::scalarslice(int x, int y)
{
	//set the resolution
	R[0] = x;
	R[1] = y;

	//allocate memory on the GPU
	HANDLE_ERROR(cudaMalloc( (void**)&S, sizeof(ptype) * x * y ));
}

scalarslice::scalarslice()
{
    R[0] = R[1] = 0;
    S = NULL;
}

scalarslice::~scalarslice()
{
	HANDLE_ERROR(cudaFree(S));
	S = NULL;
}

void scalarslice::toImage(std::string filename, ptype vmin, ptype vmax, rts::colormap::colormapType cmap)
{
	rts::colormap::gpu2image<ptype>(S, filename, R[0], R[1], vmin, vmax, cmap);
}

void scalarslice::toImage(std::string filename, bool positive, rts::colormap::colormapType cmap)
{
    cublasStatus_t stat;
    cublasHandle_t handle;

    //create a CUBLAS handle
    stat = cublasCreate(&handle);
    if(stat != CUBLAS_STATUS_SUCCESS)
    {
        std::cout<<"CUBLAS Error: initialization failed"<<std::endl;
        exit(1);
    }

    //find the index of the value with maximum magnitude
    int N = R[0] * R[1];
    int result;
    stat = cublasIsamax(handle, N, S, 1, &result);

    //std::cout<<"Maximum index: "<<result<<std::endl;

    //retrieve the maximum value
    ptype maxVal;
    HANDLE_ERROR(cudaMemcpy(&maxVal, S + result, sizeof(ptype), cudaMemcpyDeviceToHost));

    //destroy the CUBLAS handle
    cublasDestroy(handle);

    //output the image
    if(positive)
        toImage(filename, 0, maxVal, cmap);
    else
        toImage(filename, -maxVal, maxVal, cmap);
}

void scalarslice::toEnvi(std::string filename, ptype wavelength, bool append)
{
    std::string mode;
    if(append) mode = "a";
    else       mode = "w";

    //open the ENVI file
    EnviFile outfile(filename, mode);

    //get the scalar slice from the GPU to the CPU
    int memsize = sizeof(ptype) * R[0] * R[1];
    ptype* cpuData = (ptype*) malloc( memsize );
    HANDLE_ERROR(cudaMemcpy( cpuData, S, memsize, cudaMemcpyDeviceToHost));

    //add a band to the ENVI file
    outfile.addBand(cpuData, R[0], R[1], wavelength);

    outfile.close();


}

void scalarslice::clear()
{
	//this function sets the slice to zero
	if(S != NULL)
		//HANDLE_ERROR(cudaMalloc( (void**)&S, sizeof(ptype) * R[0] * R[1] ));
		HANDLE_ERROR(cudaMemset(S, 0, sizeof(ptype) * R[0] * R[1]));
}