mirror of
https://github.com/MartinOpat/cuda-based-raytrace.git
synced 2025-06-07 02:13:10 +02:00
FieldData structs implemented
This commit is contained in:
1 parent
ac63abe93a
commit
0db764c52f
10 files changed
+196
-90
No files matched your search
@@ -1,60 +0,0 @@
|
||||
#include "datareader.h"
|
||||
|
||||
#include <netcdf>
|
||||
|
||||
using namespace std;
|
||||
using namespace netCDF;
|
||||
|
||||
std::vector<float> readData(std::string path, std::string variableName) {
|
||||
netCDF::NcFile data(path, netCDF::NcFile::read);
|
||||
|
||||
multimap<string, NcVar> vars = data.getVars();
|
||||
|
||||
NcVar var = vars.find(variableName)->second;
|
||||
|
||||
int length = 1;
|
||||
for (NcDim dim: var.getDims()) {
|
||||
length *= dim.getSize();
|
||||
}
|
||||
|
||||
vector<float> vec(length);
|
||||
|
||||
var.getVar(vec.data());
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::pair<float*, size_t> loadDataToDevice(std::string path, std::string variableName) {
|
||||
netCDF::NcFile data(path, netCDF::NcFile::read);
|
||||
|
||||
multimap<string, NcVar> vars = data.getVars();
|
||||
|
||||
NcVar var = vars.find(variableName)->second;
|
||||
|
||||
int length = 1;
|
||||
for (NcDim dim: var.getDims()) {
|
||||
length *= dim.getSize();
|
||||
}
|
||||
|
||||
// Store NetCDF variable in pinned memory on host
|
||||
float *h_array;
|
||||
|
||||
cudaMallocHost(&h_array, sizeof(float)*length);
|
||||
|
||||
var.getVar(h_array);
|
||||
|
||||
// Copy data to device
|
||||
float *d_array;
|
||||
|
||||
cudaError_t status = cudaMalloc(&d_array, sizeof(float)*length);
|
||||
if (status != cudaSuccess)
|
||||
cout << "Error allocating memory: " << status << "\n";
|
||||
|
||||
cudaMemcpyAsync(d_array, h_array, sizeof(float)*length, cudaMemcpyHostToDevice);
|
||||
|
||||
cudaDeviceSynchronize(); // Heavy hammer synchronisation // TODO: Use streams
|
||||
|
||||
cudaFreeHost(h_array);
|
||||
|
||||
return std::pair(d_array, length);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef DATAREADER_H
|
||||
#define DATAREADER_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
std::vector<float> readData(std::string path, std::string variableName);
|
||||
std::pair<float*, size_t> loadDataToDevice(std::string path, std::string variableName);
|
||||
|
||||
#endif //DATAREADER_H
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "fielddata.h"
|
||||
|
||||
// __device__ float getVal(
|
||||
// const FieldMetadata &md,
|
||||
// const FieldData &d,
|
||||
// const size_t &timeInd,
|
||||
// const size_t &lonInd,
|
||||
// const size_t &latInd,
|
||||
// const size_t &levInd
|
||||
// ) {
|
||||
// return d.valArrays[0][timeInd];
|
||||
// }
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef FIELDDATA_H
|
||||
#define FIELDDATA_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct FieldMetadata {
|
||||
size_t widthSize; // Number of different longitudes
|
||||
size_t heightSize; // Number of different latitudes
|
||||
size_t depthSize; // Number of different levels
|
||||
|
||||
// lons is a managed Unified Memory array of size widthCount that indicates
|
||||
// that getVal(t, i, j, k) is a value with longitude of lons[i].
|
||||
// The other such arrays are similarly defined.
|
||||
double *lons;
|
||||
double *lats;
|
||||
double *levs;
|
||||
};
|
||||
|
||||
using FieldMetadata = FieldMetadata;
|
||||
|
||||
struct FieldData {
|
||||
static constexpr size_t FILESNUM = 2; // Number of files stored in a FieldData struct.
|
||||
|
||||
// An array of length FILESNUM storing pointers to 4D arrays stored in device memory.
|
||||
float *valArrays[FILESNUM];
|
||||
|
||||
size_t timeSize; // Number of different times
|
||||
// times is a managed Unified Memory array of size timeSize that indicates
|
||||
// that getVal(md, d, t, i, j, k) is a value at time times[t].
|
||||
int *times;
|
||||
};
|
||||
|
||||
using FieldData = FieldData;
|
||||
|
||||
// __device__ float getVal(
|
||||
// const FieldMetadata &md,
|
||||
// const FieldData &d,
|
||||
// const size_t &timeInd,
|
||||
// const size_t &lonInd,
|
||||
// const size_t &latInd,
|
||||
// const size_t &levInd
|
||||
// );
|
||||
|
||||
#endif //FIELDDATA_H
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "gpubuffer.h"
|
||||
#include "fielddata.h"
|
||||
#include "gpubufferhelper.h"
|
||||
|
||||
#include <netcdf>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace netCDF;
|
||||
|
||||
GPUBuffer::GPUBuffer(std::string path, std::string variableName):
|
||||
path(path), variableName(variableName) {
|
||||
NcFile data(path, NcFile::read);
|
||||
|
||||
multimap<string, NcVar> vars = data.getVars();
|
||||
|
||||
cudaMallocManaged(&fmd, sizeof(FieldMetadata));
|
||||
|
||||
readAndAllocateAxis<double>(&fmd->lons, &fmd->widthSize, vars.find("lon")->second);
|
||||
readAndAllocateAxis<double>(&fmd->lats, &fmd->heightSize, vars.find("lat")->second);
|
||||
readAndAllocateAxis<double>(&fmd->levs, &fmd->depthSize, vars.find("lev")->second);
|
||||
}
|
||||
|
||||
|
||||
|
||||
FieldData GPUBuffer::nextFieldData() {
|
||||
NcFile data(path, NcFile::read);
|
||||
|
||||
multimap<string, NcVar> vars = data.getVars();
|
||||
|
||||
FieldData fd;
|
||||
size_t timeSize;
|
||||
readAndAllocateAxis(&fd.times, &fd.timeSize, vars.find("time")->second);
|
||||
|
||||
NcVar var = vars.find(variableName)->second;
|
||||
|
||||
int length = 1;
|
||||
for (NcDim dim: var.getDims()) {
|
||||
length *= dim.getSize();
|
||||
}
|
||||
|
||||
// Store NetCDF variable in pinned memory on host
|
||||
float *h_array;
|
||||
|
||||
cudaMallocHost(&h_array, sizeof(float)*length);
|
||||
|
||||
var.getVar(h_array);
|
||||
|
||||
// Copy data to device
|
||||
// float *d_array;
|
||||
|
||||
cudaError_t status = cudaMalloc(&fd.valArrays[0], sizeof(float)*length);
|
||||
if (status != cudaSuccess)
|
||||
cout << "Error allocating memory: " << status << "\n";
|
||||
|
||||
cudaMemcpyAsync(fd.valArrays[0], h_array, sizeof(float)*length, cudaMemcpyHostToDevice);
|
||||
|
||||
cudaDeviceSynchronize(); // Heavy hammer synchronisation // TODO: Use streams
|
||||
|
||||
cudaFreeHost(h_array);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
GPUBuffer::~GPUBuffer() {
|
||||
cudaFree(fmd->lons);
|
||||
cudaFree(fmd->lats);
|
||||
cudaFree(fmd->levs);
|
||||
cudaFree(fmd);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef GPUBUFFER_H
|
||||
#define GPUBUFFER_H
|
||||
|
||||
#include "fielddata.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class GPUBuffer {
|
||||
public:
|
||||
GPUBuffer(std::string path, std::string variableName);
|
||||
|
||||
FieldData nextFieldData();
|
||||
|
||||
~GPUBuffer();
|
||||
|
||||
FieldMetadata *fmd;
|
||||
private:
|
||||
// TODO: Implement GPUBuffer
|
||||
std::string path;
|
||||
std::string variableName;
|
||||
|
||||
};
|
||||
|
||||
#endif //GPUBUFFER_H
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <netcdf>
|
||||
#include <cassert>
|
||||
template <typename T>
|
||||
void readAndAllocateAxis(T** axis_ptr, size_t *size, const netCDF::NcVar &var) {
|
||||
assert(var.getDimCount() == 1);
|
||||
netCDF::NcDim dim = var.getDim(0);
|
||||
*size = dim.getSize();
|
||||
cudaError_t status = cudaMallocManaged(axis_ptr, *size*sizeof(T));
|
||||
var.getVar(*axis_ptr);
|
||||
}
|
||||