* Executes the inference for given input tensors in Async fashion. * @param inputs Tensor map for the model inputs, keyed by the input node * names. * @param outputs Optional. output node name from the Tensorflow model, * if no outputs are specified, the default outputs of the model woul
(
inputs: NamedTensorMap, outputs?: string[], isFunctionExecution = false,
tensorArrayMap: TensorArrayMap = {},
tensorListMap: TensorListMap = {})
| 456 | * function execution. |
| 457 | */ |
| 458 | private async _executeAsync( |
| 459 | inputs: NamedTensorMap, outputs?: string[], isFunctionExecution = false, |
| 460 | tensorArrayMap: TensorArrayMap = {}, |
| 461 | tensorListMap: TensorListMap = {}): Promise<Tensor[]> { |
| 462 | // Dispose any tensors from a prior run to avoid leaking them. |
| 463 | this.disposeIntermediateTensors(); |
| 464 | if (!isFunctionExecution) { |
| 465 | inputs = this.mapInputs(inputs); |
| 466 | this.checkInputs(inputs); |
| 467 | this.checkInputShapeAndType(inputs); |
| 468 | outputs = this.mapOutputs(outputs); |
| 469 | this.checkOutputs(outputs); |
| 470 | } |
| 471 | |
| 472 | // Keep tensors if KEEP_INTERMEDIATE_TENSORS is on. |
| 473 | try { |
| 474 | this.keepIntermediateTensors = env().getBool('KEEP_INTERMEDIATE_TENSORS'); |
| 475 | } catch (e) { |
| 476 | this.keepIntermediateTensors = false; |
| 477 | console.warn(e.message); |
| 478 | } |
| 479 | |
| 480 | const context = new ExecutionContext( |
| 481 | this.weightMap, tensorArrayMap, tensorListMap, this.functionExecutorMap, |
| 482 | this.parseNodeNameCache); |
| 483 | |
| 484 | if (this.keepIntermediateTensors) { |
| 485 | this.clonedTensorsMap = this.cloneTensorMap(this.weightMap); |
| 486 | } |
| 487 | |
| 488 | // Graph with control flow op requires runtime evaluation of the execution |
| 489 | // order, while without control flow the execution order is pre-determined |
| 490 | // in the compile method. |
| 491 | const tensorsMap = await this.executeWithControlFlow( |
| 492 | inputs, context, outputs, isFunctionExecution); |
| 493 | const results = outputs.map(name => getTensor(name, tensorsMap, context)); |
| 494 | |
| 495 | // dispose all the intermediate tensors |
| 496 | const outputIds = results.map(t => t.id); |
| 497 | const inputIds = Object.keys(inputs).map(name => inputs[name].id); |
| 498 | const keepIds = |
| 499 | new Set<number>([...outputIds, ...inputIds, ...this.weightIds]); |
| 500 | |
| 501 | Object.values(tensorsMap).forEach(tensorsList => { |
| 502 | tensorsList.forEach(tensor => { |
| 503 | if (tensor && !tensor.isDisposed && !keepIds.has(tensor.id)) { |
| 504 | tensor.dispose(); |
| 505 | } |
| 506 | }); |
| 507 | }); |
| 508 | |
| 509 | // dispose the context for the root executor |
| 510 | if (this.parent == null) { |
| 511 | context.dispose(keepIds); |
| 512 | } |
| 513 | |
| 514 | return results; |
| 515 | } |
no test coverage detected