SCM tf_run(SCM scm_session, SCM scm_input, SCM scm_output) { SCM retval; if (scm_is_true(scm_list_p(scm_output))) { struct tf_session_t *session = get_tf_session(scm_session); int ninputs = scm_ilength(scm_input); TF_Output *inputs = scm_gc_malloc(sizeof(TF_Output) * ninputs, "tf-run"); TF_Tensor **input_values = scm_gc_malloc(sizeof(TF_Tensor *) * ninputs, "tf-run"); for (int i=0; i<ninputs; i++) { memcpy(&inputs[i], &get_tf_output(scm_caar(scm_input))->output, sizeof(TF_Output)); input_values[i] = get_tf_tensor(scm_cdar(scm_input))->tensor; scm_input = scm_cdr(scm_input); }; int noutputs = scm_ilength(scm_output); TF_Output *output = scm_gc_malloc(sizeof(TF_Output) * noutputs, "tf-run"); TF_Tensor **output_values = scm_gc_malloc(sizeof(TF_Tensor *) * noutputs, "tf-run"); for (int i=0; i<noutputs; i++) { output[i] = get_tf_output(scm_car(scm_output))->output; scm_output = scm_cdr(scm_output); }; TF_SessionRun(session->session, NULL, inputs, input_values, ninputs, output, output_values, noutputs, NULL, 0, NULL, status()); if (TF_GetCode(_status) != TF_OK) scm_misc_error("tf-run", TF_Message(_status), SCM_EOL); retval = SCM_EOL; for (int i=noutputs-1; i>=0; i--) { SCM element; struct tf_tensor_t *result = (struct tf_tensor_t *)scm_gc_calloc(sizeof(struct tf_tensor_t), "make-tensor"); SCM_NEWSMOB(element, tf_tensor_tag, result); result->tensor = output_values[i]; retval = scm_cons(element, retval); }; } else retval = scm_car(tf_run(scm_session, scm_input, scm_list_1(scm_output))); return retval; }
DNNReturnType ff_dnn_execute_model_tf(const DNNModel *model) { TFModel *tf_model = (TFModel *)model->model; TF_Tensor *output_tensor; 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{ memcpy(tf_model->output_data->data, TF_TensorData(output_tensor), tf_model->output_data->height * tf_model->output_data->width * tf_model->output_data->channels * sizeof(float)); TF_DeleteTensor(output_tensor); return DNN_SUCCESS; } }
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; }