Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with Matrex #17

Open
versilov opened this issue Jun 29, 2018 · 10 comments
Open

Integration with Matrex #17

versilov opened this issue Jun 29, 2018 · 10 comments

Comments

@versilov
Copy link
Contributor

I can see two ways for integration:

  1. "Tight" — when Tensorflex methods directly accept Matrex objects and return them.
  2. "Loose" — when we use transfer methods, like tensor_from_matrex/1 to derive tensors from Matrex objects.

My suggestion is to go with the loose method for now and to consider tight integration in some experimental branch.

@versilov
Copy link
Contributor Author

versilov commented Jun 29, 2018

Performance consideration on data transfer from Matrex into TensorFlow.

Matrex stores data in a binary, and it's possible to pass that binary into TF.
The drawback is that binary can be garbage collected by VM, while still in use by TF, which will crush VM.

So now we have to copy that binary into another one allocated with enif_alloc/1. This can become a serious bottleneck on large tensors.

It would be nice if we could just increase reference counter for that binary, when passing into TF and decrease it back, when TF calls our deallocator.

@josevalim
Copy link
Contributor

@versilov can you create a reference to the binary using sub binaries and keep it around and erase the reference once you are done with the TF call? More info: http://erlang.org/doc/man/erl_nif.html#enif_make_sub_binary

@versilov
Copy link
Contributor Author

Nice idea! Will try today.

@anshuman23
Copy link
Owner

@versilov I have tried using the array branch but when I do mix compile or iex -S mix I am getting too many warnings and error(s) from the C Matrex code.

However, the general Matrex package compiles just fine. Any dependencies included in the C array code that I should possess?

Here is the output log:

Creating NIF: priv/nifs.so
In file included from native/nifs/nifs.c:88:0:
native/nifs/nifs.h: In function ‘argmax_byte’:
native/nifs/nifs.h:60:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
In file included from native/nifs/nifs.c:88:0:
native/nifs/nifs.h: In function ‘dot_byte’:
native/nifs/nifs.h:438:38: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                      ^
native/nifs/nifs.h:438:77: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                             ^
native/nifs/nifs.h: In function ‘dot_and_add_byte’:
native/nifs/nifs.h:445:46: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_and_add, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                              ^
native/nifs/nifs.h:445:85: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_and_add, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                     ^
native/nifs/nifs.h: In function ‘dot_nt_byte’:
native/nifs/nifs.h:452:41: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_nt, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                         ^
native/nifs/nifs.h:452:80: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_nt, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                ^
native/nifs/nifs.h: In function ‘dot_tn_byte’:
native/nifs/nifs.h:459:41: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_tn, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                         ^
native/nifs/nifs.h:459:80: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_tn, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                ^
native/nifs/nifs.h: In function ‘find_byte’:
native/nifs/nifs.h:543:3: error: non-floating-point argument in call to function ‘__builtin_isnan’
   if (isnan(*element_data)) {
   ^
native/nifs/nifs.h:545:7: error: non-floating-point argument in call to function ‘__builtin_isnan’
       if (isnan(matrix_data[i]))
       ^
native/nifs/nifs.h: In function ‘from_range_byte’:
native/nifs/nifs.h:570:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t index = 0; index < result_size; index += 1)
                                 ^
native/nifs/nifs.h: In function ‘max_byte’:
native/nifs/nifs.h:587:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘min_byte’:
native/nifs/nifs.h:604:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘set_column_byte’:
native/nifs/nifs.h:758:13: warning: unused variable ‘result_size’ [-Wunused-variable]
   uint64_t  result_size;
             ^
In file included from native/nifs/nifs.c:94:0:
native/nifs/nifs.h: In function ‘argmax_int16’:
native/nifs/nifs.h:60:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
In file included from native/nifs/nifs.c:94:0:
native/nifs/nifs.h: In function ‘dot_int16’:
native/nifs/nifs.h:438:38: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                      ^
native/nifs/nifs.h:438:77: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                             ^
native/nifs/nifs.h: In function ‘dot_and_add_int16’:
native/nifs/nifs.h:445:46: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_and_add, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                              ^
native/nifs/nifs.h:445:85: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_and_add, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                     ^
native/nifs/nifs.h: In function ‘dot_nt_int16’:
native/nifs/nifs.h:452:41: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_nt, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                         ^
native/nifs/nifs.h:452:80: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_nt, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                ^
native/nifs/nifs.h: In function ‘dot_tn_int16’:
native/nifs/nifs.h:459:41: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_tn, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                         ^
native/nifs/nifs.h:459:80: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_tn, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                ^
native/nifs/nifs.h: In function ‘find_int16’:
native/nifs/nifs.h:543:3: error: non-floating-point argument in call to function ‘__builtin_isnan’
   if (isnan(*element_data)) {
   ^
native/nifs/nifs.h:545:7: error: non-floating-point argument in call to function ‘__builtin_isnan’
       if (isnan(matrix_data[i]))
       ^
native/nifs/nifs.h: In function ‘from_range_int16’:
native/nifs/nifs.h:570:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t index = 0; index < result_size; index += 1)
                                 ^
native/nifs/nifs.h: In function ‘max_int16’:
native/nifs/nifs.h:587:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘min_int16’:
native/nifs/nifs.h:604:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘set_column_int16’:
native/nifs/nifs.h:758:13: warning: unused variable ‘result_size’ [-Wunused-variable]
   uint64_t  result_size;
             ^
In file included from native/nifs/nifs.c:100:0:
native/nifs/nifs.h: In function ‘argmax_int32’:
native/nifs/nifs.h:60:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
In file included from native/nifs/nifs.c:100:0:
native/nifs/nifs.h: In function ‘dot_int32’:
native/nifs/nifs.h:438:38: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                      ^
native/nifs/nifs.h:438:77: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                             ^
native/nifs/nifs.h: In function ‘dot_and_add_int32’:
native/nifs/nifs.h:445:46: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_and_add, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                              ^
native/nifs/nifs.h:445:85: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_and_add, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                     ^
native/nifs/nifs.h: In function ‘dot_nt_int32’:
native/nifs/nifs.h:452:41: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_nt, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                         ^
native/nifs/nifs.h:452:80: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_nt, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                ^
native/nifs/nifs.h: In function ‘dot_tn_int32’:
native/nifs/nifs.h:459:41: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_tn, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                         ^
native/nifs/nifs.h:459:80: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_tn, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                ^
native/nifs/nifs.h: In function ‘random_int32’:
native/nifs/nifs.h:470:27: warning: left shift count >= width of type [-Wshift-count-overflow]
   const TYPE max_val = (1 << sizeof(TYPE) * 8) - 1;
                           ^
native/nifs/nifs.h: In function ‘find_int32’:
native/nifs/nifs.h:543:3: error: non-floating-point argument in call to function ‘__builtin_isnan’
   if (isnan(*element_data)) {
   ^
native/nifs/nifs.h:545:7: error: non-floating-point argument in call to function ‘__builtin_isnan’
       if (isnan(matrix_data[i]))
       ^
native/nifs/nifs.h: In function ‘from_range_int32’:
native/nifs/nifs.h:570:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t index = 0; index < result_size; index += 1)
                                 ^
native/nifs/nifs.h: In function ‘max_int32’:
native/nifs/nifs.h:587:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘min_int32’:
native/nifs/nifs.h:604:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘set_column_int32’:
native/nifs/nifs.h:758:13: warning: unused variable ‘result_size’ [-Wunused-variable]
   uint64_t  result_size;
             ^
In file included from native/nifs/nifs.c:106:0:
native/nifs/nifs.h: In function ‘argmax_int64’:
native/nifs/nifs.h:60:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
In file included from native/nifs/nifs.c:106:0:
native/nifs/nifs.h: In function ‘dot_int64’:
native/nifs/nifs.h:438:38: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                      ^
native/nifs/nifs.h:438:77: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                             ^
native/nifs/nifs.h: In function ‘dot_and_add_int64’:
native/nifs/nifs.h:445:46: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_and_add, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                              ^
native/nifs/nifs.h:445:85: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_and_add, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                     ^
native/nifs/nifs.h: In function ‘dot_nt_int64’:
native/nifs/nifs.h:452:41: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_nt, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                         ^
native/nifs/nifs.h:452:80: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_nt, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                ^
native/nifs/nifs.h: In function ‘dot_tn_int64’:
native/nifs/nifs.h:459:41: warning: unused parameter ‘env’ [-Wunused-parameter]
 TYPED_NIF(dot_tn, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                         ^
native/nifs/nifs.h:459:80: warning: unused parameter ‘argv’ [-Wunused-parameter]
 TYPED_NIF(dot_tn, TYPE_NAME)(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) {
                                                                                ^
native/nifs/nifs.h: In function ‘random_int64’:
native/nifs/nifs.h:470:27: warning: left shift count >= width of type [-Wshift-count-overflow]
   const TYPE max_val = (1 << sizeof(TYPE) * 8) - 1;
                           ^
native/nifs/nifs.h: In function ‘find_int64’:
native/nifs/nifs.h:543:3: error: non-floating-point argument in call to function ‘__builtin_isnan’
   if (isnan(*element_data)) {
   ^
native/nifs/nifs.h:545:7: error: non-floating-point argument in call to function ‘__builtin_isnan’
       if (isnan(matrix_data[i]))
       ^
native/nifs/nifs.h: In function ‘from_range_int64’:
native/nifs/nifs.h:570:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t index = 0; index < result_size; index += 1)
                                 ^
native/nifs/nifs.h: In function ‘max_int64’:
native/nifs/nifs.h:587:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘min_int64’:
native/nifs/nifs.h:604:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘set_column_int64’:
native/nifs/nifs.h:758:13: warning: unused variable ‘result_size’ [-Wunused-variable]
   uint64_t  result_size;
             ^
In file included from native/nifs/nifs.c:117:0:
native/nifs/nifs.h: In function ‘argmax_float32’:
native/nifs/nifs.h:60:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘dot_and_add_float32’:
native/nifs/nifs.h:278:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(uint64_t index = 0; index < rows*cols; index += 1) {
                                 ^
native/nifs/nifs.h: In function ‘dot_and_apply_float32’:
native/nifs/nifs.h:328:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(uint64_t index = 0; index < rows*cols; index += 1) {
                                 ^
In file included from native/nifs/nifs.c:117:0:
native/nifs/nifs.h: In function ‘from_range_float32’:
native/nifs/nifs.h:570:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t index = 0; index < result_size; index += 1)
                                 ^
native/nifs/nifs.h: In function ‘max_float32’:
native/nifs/nifs.h:587:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘min_float32’:
native/nifs/nifs.h:604:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘set_column_float32’:
native/nifs/nifs.h:758:13: warning: unused variable ‘result_size’ [-Wunused-variable]
   uint64_t  result_size;
             ^
In file included from native/nifs/nifs.c:125:0:
native/nifs/nifs.h: In function ‘argmax_float64’:
native/nifs/nifs.h:60:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘dot_and_add_float64’:
native/nifs/nifs.h:278:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(uint64_t index = 0; index < rows*cols; index += 1) {
                                 ^
native/nifs/nifs.h: In function ‘dot_and_apply_float64’:
native/nifs/nifs.h:328:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(uint64_t index = 0; index < rows*cols; index += 1) {
                                 ^
In file included from native/nifs/nifs.c:125:0:
native/nifs/nifs.h: In function ‘from_range_float64’:
native/nifs/nifs.h:570:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t index = 0; index < result_size; index += 1)
                                 ^
native/nifs/nifs.h: In function ‘max_float64’:
native/nifs/nifs.h:587:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘min_float64’:
native/nifs/nifs.h:604:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int64_t i = 1; i < matrix.size / sizeof(TYPE); i++)
                         ^
native/nifs/nifs.h: In function ‘set_column_float64’:
native/nifs/nifs.h:758:13: warning: unused variable ‘result_size’ [-Wunused-variable]
   uint64_t  result_size;
             ^
Makefile:209: recipe for target 'priv/nifs.so' failed
make: *** [priv/nifs.so] Error 1
could not compile dependency :matrex, "mix compile" failed. You can recompile this dependency with "mix deps.compile matrex", update it with "mix deps.update matrex" or clean it with "mix deps.clean matrex"

@versilov
Copy link
Contributor Author

Yes, it's still in development. Sorry for that.
Will clean up before releasing, of course.

@anshuman23
Copy link
Owner

No problem. I can use the main package to integrate with Tensorflex then?

Or is it missing some functionalities?

@versilov
Copy link
Contributor Author

@josevalim I can make a sub-binary, but I could not find how to release it.
enif_release_binary/1 is declared to release only binaries allocated with enif_alloc_binary/2.

@versilov
Copy link
Contributor Author

@anshuman23 it misses two main things: arbitrary dimensions and different types (it's hardcoded for 2-dimensional float matrices.).
So, if you are not using TF in production yet, it's better to use array branch. I plan to merge it into master the next week.

@josevalim
Copy link
Contributor

@versilov maybe ask around in the Erlang Questions mailing list?

@versilov
Copy link
Contributor Author

I've sent it into Erlang mailing list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants