josephjaspers / blackcat_tensors

Matrix-Vector Library Designed for Neural Network Construction. cuda (gpu) support, openmp (multithreaded cpu) support, partial support of BLAS, expression template based implementation PTX code generation identical to hand written kernels, and support for auto-differentiation
12 stars 4 forks source link

Question: What is BC::tensors::Tensor_Base<internal_t> / how to get values of Tensor ? #31

Closed xinsuinizhuan closed 5 years ago

xinsuinizhuan commented 5 years ago

I print the average loss,but the BC can not implicit conversion to double? 1567474331(1)

josephjaspers commented 5 years ago

BC::nn::MAPE returns an "expression object" (opposed to a primitive data type).

All operations/expressions with Tensors return expression objects. Originally BC::sum returned a scalar (double, float, or int) however this was inconsistent with the rest of the framework.

To get the value you can do something like....

double error = BC::Scalar<double>(BC::nn::MAPE(hyps, outputs)).data()[0]

BC::Scalar will evaluate the expression BC::nn::MAPE(hyps, outputs) .data() //returns the internal pointer (IE double*) [0] //gets the first value of the pointer

josephjaspers commented 5 years ago

What you could do if you just want to log the error would be.... std::cout << (BC::nn::MAPE(hyps, outputs[0]) / batch_size).to_string() << std::endl;

xinsuinizhuan commented 5 years ago

Oh, i see !Thank you!

xinsuinizhuan commented 5 years ago

BC::nn::MAPE returns an "expression object" (opposed to a primitive data type).

All operations/expressions with Tensors return expression objects. Originally BC::sum returned a scalar (double, float, or int) however this was inconsistent with the rest of the framework.

To get the value you can do something like....

double error = BC::Scalar<double>(BC::nn::MAPE(hyps, outputs)).data()[0]

BC::Scalar will evaluate the expression BC::nn::MAPE(hyps, outputs) .data() //returns the internal pointer (IE double*) [0] //gets the first value of the pointer

when i use the below, run it, it break: double error = BC::Scalar(BC::nn::MAPE(hyps, outputs)).data()[0]; double average_error = error / batch_size; std::cout << "Average loss: " << average_error << std::endl; this line error:double error = BC::Scalar(BC::nn::MAPE(hyps, outputs)).data()[0]; 1567557940(1) It seems out of bound of array

xinsuinizhuan commented 5 years ago

What you could do if you just want to log the error would be.... std::cout << (BC::nn::MAPE(hyps, outputs[0]) / batch_size).to_string() << std::endl;

this expression is ok!

josephjaspers commented 5 years ago

What are you writing for this exactly: double error = BC::Scalar(BC::nn::MAPE(hyps, outputs)).data()[0]

as it works on my setup without an issue.

If this works: std::cout << (BC::nn::MAPE(hyps, outputs[0]) / batch_size).to_string() << std::endl;

this should work also: BC::Scalar<double>(BC::nn::MAPE(hyps, outputs[0]) / batch_size).data()[0];

xinsuinizhuan commented 5 years ago

BC::Scalar(BC::nn::MAPE(hyps, outputs[0]) / batch_size).data()[0];

OK.below three methods is ok: std::cout << (BC::Scalar(BC::nn::MAPE(hyps, outputs[0]).data()[0]) / batch_size).to_string() << std::endl;

std::cout << BC::Scalar(BC::nn::MAPE(hyps, outputs[0]) / batch_size).data()[0] << std::endl;

double error = (BC::Scalar(BC::nn::MAPE(hyps, outputs[0])).data())[0]; double average_error = error / batch_size; std::cout << "Average loss: " << average_error << std::endl;

josephjaspers commented 5 years ago

I believe you need to specify the argument. (BC::Scalar) BC::Scalar<double>(BC::nn::MAPE(hyps, outputs[0]) / batch_size).data()[0];

Though I would expect a compile error not a runtime error.

xinsuinizhuan commented 5 years ago

One new problem, the newest code, mnist_test_recurrent example, compile it, error as: 1567994394(1)

josephjaspers commented 5 years ago

According to Microsoft:

"The C language allows implicit narrowing conversions in assignments and initialization, and C++ follows suit, even though unexpected narrowing is a cause of many code errors. To make code safer, the C++ standard requires a diagnostic message when a narrowing conversion occurs in an initialization list. In Visual C++, the diagnostic is Compiler Error C2397 when using the uniform initialization syntax supported beginning in Visual Studio 2015. The compiler generates Compiler Warning (level 1) C4838 when using the list or aggregate initialization syntax supported by Visual Studio 2013."

https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2397?view=vs-2019

So this should actually be a warning, however Visual Studio treats it as an error.

This has been fixed as of: https://github.com/josephjaspers/blackcat_tensors/commit/34a189142a720c5a7ad37aa0b628c189658892c5

xinsuinizhuan commented 5 years ago

Oh,i see.

josephjaspers commented 5 years ago

Yeah sorry about that, I'll try to add narrowing conversion as an error so I'll catch it next time. Thanks again

xinsuinizhuan commented 5 years ago

narrowing conversion again: 1569566669(1)

shoud be:

template BCINLINE auto make_dim(const Integers&... ints) { return Dim<sizeof...(Integers)> {BC::size_t(ints)...}; }

josephjaspers commented 5 years ago

Good catch, thanks for that. I will make those changes soon

josephjaspers commented 5 years ago

Fixed with https://github.com/josephjaspers/blackcat_tensors/commit/582203819850d5f1df769a46bcea389edcee8690