SCM tf_from_tensor(SCM scm_self) { struct tf_tensor_t *self = get_tf_tensor(scm_self); int type = TF_TensorType(self->tensor); int num_dims = TF_NumDims(self->tensor); int count = 1; SCM scm_shape = SCM_EOL; for (int i=num_dims - 1; i>=0; i--) { scm_shape = scm_cons(scm_from_int(TF_Dim(self->tensor, i)), scm_shape); count = count * TF_Dim(self->tensor, i); }; size_t size = TF_TensorByteSize(self->tensor); void *data; if (type == TF_STRING) { int64_t *offsets = TF_TensorData(self->tensor); void *pointer = offsets + count; size_t str_len; data = scm_gc_malloc(sizeof(SCM) * count, "from-tensor"); SCM *result = data; for (int i=0; i<count; i++) { const char *str; size_t len; TF_StringDecode(pointer + *offsets, size - *offsets, &str, &len, status()); if (TF_GetCode(_status) != TF_OK) scm_misc_error("from-tensor", TF_Message(_status), SCM_EOL); *result++ = scm_from_locale_stringn(str, len); offsets++; }; } else { data = scm_gc_malloc_pointerless(size, "from-tensor"); memcpy(data, TF_TensorData(self->tensor), size); }; return scm_list_3(scm_from_int(type), scm_shape, scm_from_pointer(data, NULL)); }
static DNNReturnType set_input_output_tf(void *model, DNNData *input, DNNData *output) { TFModel *tf_model = (TFModel *)model; int64_t input_dims[] = {1, input->height, input->width, input->channels}; TF_SessionOptions *sess_opts; const TF_Operation *init_op = TF_GraphOperationByName(tf_model->graph, "init"); TF_Tensor *output_tensor; // Input operation should be named 'x' tf_model->input.oper = TF_GraphOperationByName(tf_model->graph, "x"); if (!tf_model->input.oper){ return DNN_ERROR; } tf_model->input.index = 0; if (tf_model->input_tensor){ TF_DeleteTensor(tf_model->input_tensor); } tf_model->input_tensor = TF_AllocateTensor(TF_FLOAT, input_dims, 4, input_dims[1] * input_dims[2] * input_dims[3] * sizeof(float)); if (!tf_model->input_tensor){ return DNN_ERROR; } input->data = (float *)TF_TensorData(tf_model->input_tensor); // Output operation should be named 'y' tf_model->output.oper = TF_GraphOperationByName(tf_model->graph, "y"); if (!tf_model->output.oper){ return DNN_ERROR; } tf_model->output.index = 0; if (tf_model->session){ TF_CloseSession(tf_model->session, tf_model->status); TF_DeleteSession(tf_model->session, tf_model->status); } sess_opts = TF_NewSessionOptions(); tf_model->session = TF_NewSession(tf_model->graph, sess_opts, tf_model->status); TF_DeleteSessionOptions(sess_opts); if (TF_GetCode(tf_model->status) != TF_OK) { return DNN_ERROR; } // Run initialization operation with name "init" if it is present in graph if (init_op){ TF_SessionRun(tf_model->session, NULL, NULL, NULL, 0, NULL, NULL, 0, &init_op, 1, NULL, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK) { return DNN_ERROR; } } // Execute network to get output height, width and number of channels TF_SessionRun(tf_model->session, NULL, &tf_model->input, &tf_model->input_tensor, 1, &tf_model->output, &output_tensor, 1, NULL, 0, NULL, tf_model->status); if (TF_GetCode(tf_model->status) != TF_OK){ return DNN_ERROR; } else{ output->height = TF_Dim(output_tensor, 1); output->width = TF_Dim(output_tensor, 2); output->channels = TF_Dim(output_tensor, 3); output->data = av_malloc(output->height * output->width * output->channels * sizeof(float)); if (!output->data){ return DNN_ERROR; } tf_model->output_data = output; TF_DeleteTensor(output_tensor); } return DNN_SUCCESS; }