Merge with master works
Signed-off-by: Micaela Verucchi <micaelaverucchi@gmail.com> Davide Sapienza <sapienza.dav@gmail.com>
This commit is contained in:
+327
@@ -0,0 +1,327 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "Layer.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weights) :
|
||||
Layer(net) {
|
||||
|
||||
this->returnSeq = returnSeq;
|
||||
int batchSize = input_dim.n;
|
||||
int inputSize = input_dim.c;
|
||||
seqLen = input_dim.w;
|
||||
stateSize = hiddensize;
|
||||
|
||||
// init Tensor Descriptors
|
||||
std::vector<cudnnTensorDescriptor_t> x_vec(seqLen);
|
||||
std::vector<cudnnTensorDescriptor_t> y_vec(seqLen);
|
||||
|
||||
int dimA[3];
|
||||
int strideA[3];
|
||||
for (int i = 0; i < seqLen; i++) {
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&x_vec[i]));
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&y_vec[i]));
|
||||
|
||||
dimA[0] = batchSize;
|
||||
dimA[1] = inputSize;
|
||||
dimA[2] = 1;
|
||||
dimA[0] = batchSize;
|
||||
dimA[1] = inputSize;
|
||||
strideA[0] = dimA[2] * dimA[1];
|
||||
strideA[1] = dimA[2];
|
||||
strideA[2] = 1;
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(x_vec[i],
|
||||
net->dataType, 3, dimA, strideA));
|
||||
|
||||
dimA[0] = batchSize;
|
||||
dimA[1] = stateSize;
|
||||
dimA[2] = 1;
|
||||
strideA[0] = dimA[2] * dimA[1];
|
||||
strideA[1] = dimA[2];
|
||||
strideA[2] = 1;
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(y_vec[i],
|
||||
net->dataType, 3, dimA, strideA));
|
||||
}
|
||||
// apply tensordesc
|
||||
x_desc_vec_ = x_vec;
|
||||
y_desc_vec_ = y_vec;
|
||||
|
||||
|
||||
// set the state tensors
|
||||
dimA[0] = numLayers;
|
||||
dimA[1] = batchSize;
|
||||
dimA[2] = stateSize;
|
||||
strideA[0] = dimA[2] * dimA[1];
|
||||
strideA[1] = dimA[2];
|
||||
strideA[2] = 1;
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&hx_desc_));
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&cx_desc_));
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&hy_desc_));
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&cy_desc_));
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(hx_desc_, net->dataType, 3, dimA, strideA));
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(cx_desc_, net->dataType, 3, dimA, strideA));
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(hy_desc_, net->dataType, 3, dimA, strideA));
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(cy_desc_, net->dataType, 3, dimA, strideA));
|
||||
// allocate dnnType *hx_ptr, *cx_ptr, *hy_ptr, *cy_ptr;
|
||||
stateDataDim = dimA[0]*dimA[1]*dimA[2];
|
||||
checkCuda( cudaMalloc(&hx_ptr, stateDataDim*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&cx_ptr, stateDataDim*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&hy_ptr, stateDataDim*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&cy_ptr, stateDataDim*sizeof(dnnType)) );
|
||||
|
||||
|
||||
|
||||
// Create Dropout descriptors // TODO: ??? IS IT NECESSARY ???
|
||||
float dropoutprob = 0.1f; // random val ????
|
||||
checkCUDNN(cudnnCreateDropoutDescriptor(&dropoutDesc));
|
||||
checkCUDNN(cudnnDropoutGetStatesSize(net->cudnnHandle, &dropout_byte_));
|
||||
dropout_size_ = dropout_byte_ / sizeof(dnnType);
|
||||
checkCuda( cudaMalloc(&dropout_states_, dropout_byte_) );
|
||||
uint64_t seed_ = 17 + rand() % 4096; // NOLINT(runtime/threadsafe_fn)
|
||||
checkCUDNN(cudnnSetDropoutDescriptor(dropoutDesc,
|
||||
net->cudnnHandle, dropoutprob, dropout_states_, dropout_byte_, seed_));
|
||||
|
||||
|
||||
// RNN descriptors
|
||||
checkCUDNN(cudnnCreateRNNDescriptor(&rnnDesc));
|
||||
|
||||
checkCUDNN(cudnnSetRNNDescriptor(net->cudnnHandle,
|
||||
rnnDesc, stateSize, numLayers, dropoutDesc,
|
||||
cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT,
|
||||
//(bidirectional ? cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL : cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL),
|
||||
cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL,
|
||||
cudnnRNNMode_t::CUDNN_LSTM,
|
||||
cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD,
|
||||
net->dataType));
|
||||
|
||||
|
||||
// Get temp space sizes
|
||||
checkCUDNN(cudnnGetRNNWorkspaceSize(net->cudnnHandle,
|
||||
rnnDesc, seqLen, x_desc_vec_.data(), &workspace_byte_));
|
||||
workspace_size_ = workspace_byte_ / sizeof(dnnType);
|
||||
checkCuda( cudaMalloc(&work_space_, workspace_byte_) );
|
||||
|
||||
|
||||
// Check that number of params are correct
|
||||
size_t cudnn_param_size;
|
||||
checkCUDNN(cudnnGetRNNParamsSize(net->cudnnHandle,
|
||||
rnnDesc,x_desc_vec_[0], &cudnn_param_size, net->dataType));
|
||||
int cudnn_params = cudnn_param_size/sizeof(dnnType);
|
||||
//std::cout<<"LSTM params size: "<<cudnn_params << ", bytes: "<<cudnn_param_size<<"\n";
|
||||
|
||||
// Set param descriptors
|
||||
checkCUDNN(cudnnCreateFilterDescriptor(&w_desc_));
|
||||
int dim_w[3] = {1, 1, 1};
|
||||
dim_w[0] = cudnn_params;
|
||||
checkCUDNN(cudnnSetFilterNdDescriptor(w_desc_,
|
||||
net->dataType, net->tensorFormat, 3, dim_w));
|
||||
|
||||
// load params
|
||||
std::cout<<"Reading weights: PARAMS="<<cudnn_params*2<<"\n";
|
||||
readBinaryFile(fname_weights, cudnn_params*2, &w_h, &w_ptr);
|
||||
// set forward and backward params
|
||||
wf_ptr = w_ptr;
|
||||
wb_ptr = w_ptr + cudnn_params;
|
||||
//std::cout<<"wf: "<<wf_ptr<<" wb "<<wb_ptr<<"\n";
|
||||
|
||||
// set output dim
|
||||
output_dim = input_dim;
|
||||
output_dim.c = stateSize*(bidirectional ? 2 : 1);
|
||||
|
||||
// if retunseq is disabled only the last timestep is returned
|
||||
if(!returnSeq) {
|
||||
output_dim.h = 1;
|
||||
output_dim.w = 1;
|
||||
}
|
||||
|
||||
//allocate data for infer result
|
||||
checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) );
|
||||
|
||||
// used during inference
|
||||
one_output_dim = input_dim;
|
||||
one_output_dim.c = stateSize;
|
||||
checkCuda( cudaMalloc(&srcF, input_dim.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&srcB, input_dim.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&dstF, one_output_dim.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&dstB_NR, one_output_dim.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&dstB, one_output_dim.tot()*sizeof(dnnType)) );
|
||||
|
||||
|
||||
/*
|
||||
// Query weight layout
|
||||
cudnnFilterDescriptor_t m_desc;
|
||||
checkCUDNN(cudnnCreateFilterDescriptor(&m_desc));
|
||||
dnnType *p;
|
||||
int n = 8; // lstm layers
|
||||
|
||||
printCenteredTitle("WEIGHTS", '=', 20);
|
||||
for (int i = 0; i < numLayers; ++i) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
|
||||
checkCUDNN(cudnnGetRNNLinLayerMatrixParams(net->cudnnHandle, rnnDesc,
|
||||
i, x_desc_vec_[0], w_desc_, 0, j, m_desc, (void**)&p));
|
||||
|
||||
std::cout << "ptr: " << ((int64_t)(p - NULL))/sizeof(dnnType)<<"\n";
|
||||
|
||||
cudnnDataType_t t;
|
||||
cudnnTensorFormat_t f;
|
||||
int ndim = 5;
|
||||
int dims[5] = {0, 0, 0, 0, 0};
|
||||
checkCUDNN(cudnnGetFilterNdDescriptor(m_desc, ndim, &t, &f, &ndim, &dims[0]));
|
||||
std::cout << "(layer, linlayer): " << i << " " << j << "\n";
|
||||
|
||||
int tot = 1;
|
||||
for (int i = 0; i < ndim; ++i) {
|
||||
std::cout << dims[i] << " ";
|
||||
tot *= dims[i];
|
||||
}
|
||||
std::cout<<"\t-> "<<tot<<"\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
printCenteredTitle("BIAS", '=', 20);
|
||||
for (int i = 0; i < numLayers; ++i) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
checkCUDNN(cudnnGetRNNLinLayerBiasParams(net->cudnnHandle, rnnDesc,
|
||||
i, x_desc_vec_[0], w_desc_, 0, j, m_desc, (void**)&p));
|
||||
|
||||
std::cout << "ptr: " << ((int64_t)(p - NULL))/sizeof(dnnType)<<"\n";
|
||||
|
||||
cudnnDataType_t t;
|
||||
cudnnTensorFormat_t f;
|
||||
int ndim = 5;
|
||||
int dims[5] = {0, 0, 0, 0, 0};
|
||||
checkCUDNN(cudnnGetFilterNdDescriptor(m_desc, ndim, &t, &f, &ndim, &dims[0]));
|
||||
std::cout << "(layer, linlayer): " << i << " " << j << "\n";
|
||||
|
||||
int tot = 1;
|
||||
for (int i = 0; i < ndim; ++i) {
|
||||
std::cout << dims[i] << " ";
|
||||
tot *= dims[i];
|
||||
}
|
||||
std::cout<<"\t-> "<<tot<<"\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
checkCUDNN(cudnnDestroyFilterDescriptor(m_desc));
|
||||
*/
|
||||
}
|
||||
|
||||
LSTM::~LSTM() {
|
||||
checkCuda(cudaFree(hx_ptr));
|
||||
checkCuda(cudaFree(cx_ptr));
|
||||
checkCuda(cudaFree(hy_ptr));
|
||||
checkCuda(cudaFree(cy_ptr));
|
||||
checkCuda(cudaFree(w_ptr ));
|
||||
|
||||
checkCuda(cudaFree(work_space_ ));
|
||||
checkCuda(cudaFree(dropout_states_));
|
||||
|
||||
checkCuda(cudaFree(srcF));
|
||||
checkCuda(cudaFree(srcB));
|
||||
checkCuda(cudaFree(dstF));
|
||||
checkCuda(cudaFree(dstB_NR));
|
||||
checkCuda(cudaFree(dstB));
|
||||
checkCuda(cudaFree(dstData));
|
||||
}
|
||||
|
||||
dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
|
||||
// transpose input
|
||||
matrixTranspose(net->cublasHandle, srcData, srcF, dim.c, dim.h*dim.w*dim.l);
|
||||
|
||||
// build srcB as reversed srcF
|
||||
for(int i=0; i<input_dim.w; i++) {
|
||||
int off_0 = i*(input_dim.c);
|
||||
int off_1 = (i+1)*(input_dim.c);
|
||||
checkCuda( cudaMemcpy(srcB + dim.tot() - off_1, srcF + off_0,
|
||||
input_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
}
|
||||
|
||||
// forward
|
||||
{
|
||||
// reset states
|
||||
checkCuda( cudaMemset(hx_ptr, 0, stateDataDim*sizeof(float)) );
|
||||
checkCuda( cudaMemset(cx_ptr, 0, stateDataDim*sizeof(float)) );
|
||||
|
||||
|
||||
checkCUDNN(cudnnRNNForwardInference(net->cudnnHandle,
|
||||
rnnDesc,
|
||||
seqLen, // number of time steps (nT)
|
||||
x_desc_vec_.data(), // input array of desc (nT*nC_in)
|
||||
srcF, // input pointer
|
||||
hx_desc_, // initial hidden state desc
|
||||
hx_ptr, // initial hidden state pointer
|
||||
cx_desc_, // initial cell state desc
|
||||
cx_ptr, // initial cell state pointer
|
||||
w_desc_, // weights desc
|
||||
wf_ptr, // weights pointer
|
||||
y_desc_vec_.data(), // output desc (nT*nC_out)
|
||||
dstF, // output pointer
|
||||
hy_desc_, // final hidden state desc
|
||||
hy_ptr, // final hidden state pointer
|
||||
cy_desc_, // final cell state desc
|
||||
cy_ptr, // final cell state pointer
|
||||
work_space_, // workspace pointer
|
||||
workspace_byte_)); // workspace size
|
||||
}
|
||||
|
||||
// backward
|
||||
{
|
||||
// reset states
|
||||
checkCuda( cudaMemset(hx_ptr, 0, stateDataDim*sizeof(float)) );
|
||||
checkCuda( cudaMemset(cx_ptr, 0, stateDataDim*sizeof(float)) );
|
||||
|
||||
checkCUDNN(cudnnRNNForwardInference(net->cudnnHandle,
|
||||
rnnDesc,
|
||||
seqLen, // number of time steps (nT)
|
||||
x_desc_vec_.data(), // input array of desc (nT*nC_in)
|
||||
srcB, // input pointer
|
||||
hx_desc_, // initial hidden state desc
|
||||
hx_ptr, // initial hidden state pointer
|
||||
cx_desc_, // initial cell state desc
|
||||
cx_ptr, // initial cell state pointer
|
||||
w_desc_, // weights desc
|
||||
wb_ptr, // weights pointer
|
||||
y_desc_vec_.data(), // output desc (nT*nC_out)
|
||||
dstB_NR, // output pointer
|
||||
hy_desc_, // final hidden state desc
|
||||
hy_ptr, // final hidden state pointer
|
||||
cy_desc_, // final cell state desc
|
||||
cy_ptr, // final cell state pointer
|
||||
work_space_, // workspace pointer
|
||||
workspace_byte_)); // workspace size
|
||||
}
|
||||
|
||||
|
||||
// reverse order of dstB
|
||||
for(int i=0; i<one_output_dim.w; i++) {
|
||||
int off_0 = i*(one_output_dim.c);
|
||||
int off_1 = (i+1)*(one_output_dim.c);
|
||||
checkCuda( cudaMemcpy(dstB + one_output_dim.tot() - off_1, dstB_NR + off_0,
|
||||
one_output_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
}
|
||||
|
||||
// if retunseq is disabled only the last timestep is returned
|
||||
if(returnSeq) {
|
||||
// forward transpose
|
||||
matrixTranspose(net->cublasHandle, dstF, dstData,
|
||||
one_output_dim.h* one_output_dim.w*one_output_dim.l, one_output_dim.c);
|
||||
// backward transpose
|
||||
matrixTranspose(net->cublasHandle, dstB, dstData + one_output_dim.tot(),
|
||||
one_output_dim.h* one_output_dim.w*one_output_dim.l, one_output_dim.c);
|
||||
} else {
|
||||
// copy last of forward
|
||||
checkCuda( cudaMemcpy(dstData, dstF + one_output_dim.tot() - one_output_dim.c,
|
||||
one_output_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
// copy first of backward
|
||||
checkCuda( cudaMemcpy(dstData + one_output_dim.c, dstB,
|
||||
one_output_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
}
|
||||
|
||||
dim = output_dim;
|
||||
return dstData;
|
||||
}
|
||||
|
||||
}}
|
||||
+6
-6
@@ -17,24 +17,24 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs,
|
||||
|
||||
std::cout<<"Reading weights: I="<<inputs<<" O="<<outputs<<" KERNEL="<<kh<<"x"<<kw<<"x"<<kl<<"\n";
|
||||
int seek = 0;
|
||||
readBinaryFile(weights_path.c_str(), inputs*outputs*kh*kw*kl, &data_h, &data_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), inputs*outputs*kh*kw*kl, &data_h, &data_d, seek);
|
||||
seek += inputs*outputs*kh*kw*kl;
|
||||
this->additional_bias = additional_bias;
|
||||
if(additional_bias) {
|
||||
readBinaryFile(weights_path.c_str(), outputs, &bias2_h, &bias2_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &bias2_h, &bias2_d, seek);
|
||||
seek += outputs;
|
||||
}
|
||||
|
||||
readBinaryFile(weights_path.c_str(), outputs, &bias_h, &bias_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &bias_h, &bias_d, seek);
|
||||
|
||||
this->batchnorm = batchnorm;
|
||||
if(batchnorm) {
|
||||
seek += outputs;
|
||||
readBinaryFile(weights_path.c_str(), outputs, &scales_h, &scales_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &scales_h, &scales_d, seek);
|
||||
seek += outputs;
|
||||
readBinaryFile(weights_path.c_str(), outputs, &mean_h, &mean_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &mean_h, &mean_d, seek);
|
||||
seek += outputs;
|
||||
readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek);
|
||||
|
||||
float eps = TKDNN_BN_MIN_EPSILON;
|
||||
|
||||
|
||||
+7
-4
@@ -7,11 +7,14 @@ namespace tk { namespace dnn {
|
||||
|
||||
Route::Route(Network *net, Layer **layers, int layers_n, bool final) : Layer(net, final) {
|
||||
|
||||
this->layers_n = layers_n;
|
||||
if(layers_n > MAX_INPUT_LAYERS)
|
||||
FatalError("Route: MAX INPUT LAYERS overload");
|
||||
for(int i=0; i<layers_n; i++)
|
||||
// copy input layers
|
||||
if(layers_n > MAX_LAYERS) {
|
||||
FatalError("ROUTE: reached max number of input layers");
|
||||
}
|
||||
for(int i=0; i<layers_n; i++) {
|
||||
this->layers[i] = layers[i];
|
||||
}
|
||||
this->layers_n = layers_n;
|
||||
|
||||
//get dims
|
||||
output_dim.l = 1;
|
||||
|
||||
+30
-31
@@ -32,43 +32,41 @@ void downloadWeightsifDoNotExist(const std::string& input_bin, const std::string
|
||||
}
|
||||
|
||||
|
||||
void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek, bool skipLoad){
|
||||
void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek)
|
||||
{
|
||||
std::ifstream dataFile (fname, std::ios::in | std::ios::binary);
|
||||
std::stringstream error_s;
|
||||
if (!dataFile)
|
||||
{
|
||||
error_s << "Error opening file " << fname;
|
||||
FatalError(error_s.str());
|
||||
}
|
||||
|
||||
if(seek != 0) {
|
||||
dataFile.seekg(seek*sizeof(dnnType), dataFile.cur);
|
||||
}
|
||||
|
||||
int size_b = size*sizeof(dnnType);
|
||||
*data_h = new dnnType[size];
|
||||
|
||||
if(!skipLoad) {
|
||||
std::ifstream dataFile(fname, std::ios::in | std::ios::binary);
|
||||
std::stringstream error_s;
|
||||
if (!dataFile) {
|
||||
error_s << "Error opening file " << fname;
|
||||
FatalError(error_s.str());
|
||||
}
|
||||
|
||||
if (seek != 0) {
|
||||
dataFile.seekg(seek * sizeof(dnnType), dataFile.cur);
|
||||
}
|
||||
|
||||
// printf("data_h %d size_b %d\n", *data_h,size_b);
|
||||
if (!dataFile.read((char *) *data_h, size_b)) {
|
||||
|
||||
error_s << "Error reading file " << fname;
|
||||
FatalError(error_s.str());
|
||||
}
|
||||
} else {
|
||||
std::cout<<COL_RED<<"WARNING: skipping data load, this should only used in debug\n"<<COL_END;
|
||||
if (!dataFile.read ((char*) *data_h, size_b))
|
||||
{
|
||||
error_s << "Error reading file " << fname << " with n of float: "<<size;
|
||||
error_s << " seek: "<<seek << " size: "<<size_b<<"\n";
|
||||
FatalError(error_s.str());
|
||||
}
|
||||
|
||||
checkCuda( cudaMalloc(data_d, size_b) );
|
||||
checkCuda( cudaMemcpy(*data_d, *data_h, size_b, cudaMemcpyHostToDevice) );
|
||||
}
|
||||
|
||||
|
||||
void printDeviceVector(int size, dnnType* vec_d, bool device){
|
||||
dnnType *vec;
|
||||
if(device) {
|
||||
vec = new dnnType[size];
|
||||
cudaDeviceSynchronize();
|
||||
cudaMemcpy(vec, vec_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost);
|
||||
cudaDeviceSynchronize();
|
||||
checkCuda(cudaDeviceSynchronize());
|
||||
checkCuda(cudaMemcpy(vec, vec_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost));
|
||||
checkCuda(cudaDeviceSynchronize());
|
||||
} else {
|
||||
vec = vec_d;
|
||||
}
|
||||
@@ -82,7 +80,7 @@ void printDeviceVector(int size, dnnType* vec_d, bool device){
|
||||
delete [] vec;
|
||||
}
|
||||
|
||||
int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device) {
|
||||
int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device, int limit) {
|
||||
|
||||
dnnType *data_h, *correct_h;
|
||||
const float eps = 0.02f;
|
||||
@@ -90,10 +88,11 @@ int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device) {
|
||||
if(device) {
|
||||
data_h = new dnnType[size];
|
||||
correct_h = new dnnType[size];
|
||||
cudaDeviceSynchronize();
|
||||
cudaMemcpy(data_h, data_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost);
|
||||
cudaMemcpy(correct_h, correct_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost);
|
||||
cudaDeviceSynchronize();
|
||||
checkCuda(cudaDeviceSynchronize());
|
||||
checkCuda(cudaMemcpy(data_h, data_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost));
|
||||
checkCuda(cudaMemcpy(correct_h, correct_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost));
|
||||
checkCuda(cudaDeviceSynchronize());
|
||||
|
||||
} else {
|
||||
data_h = data_d;
|
||||
correct_h = correct_d;
|
||||
@@ -105,7 +104,7 @@ int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device) {
|
||||
diffs += 1;
|
||||
if(diffs == 1)
|
||||
std::cout<<"\n";
|
||||
if(diffs < 10)
|
||||
if(diffs < limit)
|
||||
std::cout<<" | [ "<<i<<" ]: "<<data_h[i]<<" "<<correct_h[i]<<"\n";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user