-
Notifications
You must be signed in to change notification settings - Fork 76
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
Problems with namespaces #117
Comments
Hi @Hakan-Eyilmez, can you please provide your custom adapter and example model/graph so that we may reproduce this locally? Thanks. |
Hello @pkgoogle, I am sorry for the inconvenience. Below I provide the code to an example adapter, which was based on your "my_adapter" adapter, with a few additions, and the graph, it produces. |
Hi @Hakan-Eyilmez, thanks for the extra information, it always helps to add as much context as possible. The problem appears to be with single nodes within a namespace. I can replicate your issue with your exact adapter, but I noticed "SanFrancisco" is a layer/namespace not a node. I am able to accomplish something similar to want you want if I add an extra node within the "Cities/NewYork" layer/namespace if I incorporate it as such... example (notice I don't have a "NewYork" node): from typing import Dict
from model_explorer import (Adapter, AdapterMetadata, ModelExplorerGraphs,
graph_builder)
class MyAdapter(Adapter):
"""A simple adapter that returns a hard-coded graph.
See more info at:
https://github.com/google-ai-edge/model-explorer/wiki/6.-Develop-Adapter-Extension
"""
metadata = AdapterMetadata(id='my-adapter',
name='My first adapter',
description='My first adapter!',
source_repo='https://github.com/user/my_adapter',
fileExts=['test'])
# This is required.
def __init__(self):
super().__init__()
def convert(self, model_path: str, settings: Dict) -> ModelExplorerGraphs:
# Create a graph for my road trip.
graph = graph_builder.Graph(id='road_trip')
###################
# Add nodes.
# Create start and end node.
#
# They are located at root level hence the empty `namespace` parameter.
vancouver = graph_builder.GraphNode(
id='vancouver', label='Vancouver', namespace='')
la = graph_builder.GraphNode(id='la', label='Los Angeles', namespace='')
# Create a node for Seattle and put it into a 'coastal drive' layer.
seattle = graph_builder.GraphNode(
id='seattle', label='Seatttttle', namespace='CoastalDrive')
# Create San Franciso as a sublayer of the CoastalDrive layer and add some
# tourist sites there.
sf_golden_gate_bridge = graph_builder.GraphNode(
id='sf_golden_gate_bridge', label='Golden gate bridge',
namespace='CoastalDrive/SanFrancisco')
sf_pier_39 = graph_builder.GraphNode(
id='sf_pier_39', label='PIER 39',
namespace='CoastalDrive/SanFrancisco')
# Create another two cities and put them into an 'inland drive' layer.
salt_lake_city = graph_builder.GraphNode(
id='salt_lake_city', label='Salt lake city', namespace='InlandDrive')
las_vegas = graph_builder.GraphNode(
id='las_vegas', label='Las Vegas', namespace='InlandDrive')
# Custom nodes from Hakan
# new_york = graph_builder.GraphNode(
# id='new_york', label='New York', namespace='Cities')
central_park = graph_builder.GraphNode(
id='central_park', label='Central Park', namespace='Cities/NewYork')
statue_of_liberty = graph_builder.GraphNode(
id='statue_of_liberty', label='Statue of Liberty', namespace='Cities/NewYork')
washington = graph_builder.GraphNode(
id='washington', label='Washington DC', namespace='Cities')
# Add all the nodes into graph.
graph.nodes.extend([vancouver, la, seattle, sf_golden_gate_bridge,
sf_pier_39, salt_lake_city, las_vegas, central_park, statue_of_liberty, washington])
###################
# Add edges.
# Connect edges along the cities for coastal drive.
la.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='sf_pier_39'))
sf_pier_39.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='sf_golden_gate_bridge'))
sf_golden_gate_bridge.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='seattle'))
seattle.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='vancouver'))
# Connect edges along the cities for inland drive.
#
# LA has two incoming edges from pier_39 and las_vegas.
# We use targetNodeInputId to identify these two edges. pier_39 goes into
# input id '0' (default), and las_vegas goes into input id '1'.
la.incomingEdges.append(graph_builder.IncomingEdge(
sourceNodeId='las_vegas', targetNodeInputId='1'))
las_vegas.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='salt_lake_city'))
# Custom connections of City nodes
washington.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='statue_of_liberty'))
central_park.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='vancouver'))
statue_of_liberty.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='central_park'))
la.incomingEdges.append(graph_builder.IncomingEdge(
sourceNodeId='washington', targetNodeInputId='2'))
# Vancouver has two outgoing edges to seattle and salt_lake_city.
# We use sourceNodeOutputId to identify these two edges. Vancouver's output
# id '0' (default) goes to seattle, and its output id '1' goes to salt_lake_city.
salt_lake_city.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='vancouver',
sourceNodeOutputId='1'))
#######################
# Add node attributes.
temperatures = ['52F', '74F', '55F', '64F', '65F', '62F', '90F', '88F', '82F', '108F']
for i, node in enumerate(graph.nodes):
node.attrs.append(graph_builder.KeyValue(
key="temperature", value=temperatures[i]))
#######################
# Add outputs metadata.
# This is the edge from vancouver to seattle.
vancouver.outputsMetadata.append(graph_builder.MetadataItem(
# This identifies which output id the metadata attached to.
#
# From the "add edges" section we know that output id "0" connects to
# seattle.
id='0',
attrs=[graph_builder.KeyValue(key='distance', value='230 km'),
# "__tensor_tag" is a special metadata key whose value will be
# used as output name in side panel.
graph_builder.KeyValue(key='__tensor_tag', value='coastal')]))
# This is the edge from vancouver to salt_lake_city.
vancouver.outputsMetadata.append(graph_builder.MetadataItem(
# From the "add edges" section we know that output id "1" connects to
# salt_lake_city.
id='1',
attrs=[graph_builder.KeyValue(key='distance', value='1554 km'),
graph_builder.KeyValue(key='__tensor_tag', value='inland')]))
vancouver.outputsMetadata.append(graph_builder.MetadataItem(
# From the "add edges" section we know that output id "2" connects to
# new_york
id='2',
attrs=[graph_builder.KeyValue(key='distance', value='154 km'),
graph_builder.KeyValue(key='__tensor_tag', value='cities')]))
# Add other distances
def add_distance_output_metadata(from_node: graph_builder.GraphNode, distance: str):
from_node.outputsMetadata.append(graph_builder.MetadataItem(
id='0',
attrs=[graph_builder.KeyValue(key='distance', value=distance)]))
add_distance_output_metadata(salt_lake_city, '677 km')
add_distance_output_metadata(las_vegas, '439 km')
add_distance_output_metadata(seattle, '1310 km')
add_distance_output_metadata(sf_golden_gate_bridge, '10 km')
add_distance_output_metadata(sf_pier_39, '613 km')
add_distance_output_metadata(central_park, '1490 km')
add_distance_output_metadata(washington, '405 km')
#######################
# Add inputs metadata.
la.inputsMetadata.append(graph_builder.MetadataItem(
id='0', attrs=[graph_builder.KeyValue(key='__tensor_tag', value='coastal')]))
la.inputsMetadata.append(graph_builder.MetadataItem(
id='1', attrs=[graph_builder.KeyValue(key='__tensor_tag', value='inland')]))
la.inputsMetadata.append(graph_builder.MetadataItem(
id='2', attrs=[graph_builder.KeyValue(key='__tensor_tag', value='cities')]))
return {'graphs': [graph]} If I remove the extra node ("statue_of_liberty") It reverts to what you say: # Custom nodes from Hakan
# new_york = graph_builder.GraphNode(
# id='new_york', label='New York', namespace='Cities')
central_park = graph_builder.GraphNode(
id='central_park', label='Central Park', namespace='Cities/NewYork')
# statue_of_liberty = graph_builder.GraphNode(
# id='statue_of_liberty', label='Statue of Liberty', namespace='Cities/NewYork')
....
# Add all the nodes into graph.
graph.nodes.extend([vancouver, la, seattle, sf_golden_gate_bridge,
sf_pier_39, salt_lake_city, las_vegas, central_park, washington])
....
# Custom connections of City nodes
washington.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='central_park'))
central_park.incomingEdges.append(
graph_builder.IncomingEdge(sourceNodeId='vancouver'))
# statue_of_liberty.incomingEdges.append(
# graph_builder.IncomingEdge(sourceNodeId='central_park'))
la.incomingEdges.append(graph_builder.IncomingEdge(
sourceNodeId='washington', targetNodeInputId='2')) @jinjingforever can you please take a look at the single node issue? Thanks. |
Hi @Hakan-Eyilmez sorry for the confusion! Model explorer would automatically remove the group/layer node if it only has one single op-node child. This is mainly for better readability. There is a setting to turn this off: I will add this to the user guide and the adapter development guide. Thank you! |
Hello,
I am currently writing a custom adapter and have encountered an issue with namespaces. In multiple instances, the model ignores the specified namespace. Below is a simple example where "Central Park" is displayed outside its namespace. Is this behavior intentional? If so, would it be possible to include a feature to toggle this on or off?
The text was updated successfully, but these errors were encountered: