File size: 10,033 Bytes
7f8181f
 
d715409
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7f8181f
 
 
 
d715409
 
 
 
 
 
 
 
7f8181f
 
d715409
 
 
 
 
 
 
 
 
 
1ff8412
 
 
2fd72f3
 
 
 
 
 
 
 
 
 
 
 
 
d715409
2fd72f3
 
 
 
 
 
 
 
d715409
 
2fd72f3
d715409
 
2fd72f3
 
 
 
1ff8412
2fd72f3
d715409
 
 
 
2fd72f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d715409
 
 
7f8181f
d715409
 
7f8181f
 
1ff8412
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
import gradio as gr

js = """
function appJS() {
  document.getElementById("plugin-selector-submit").addEventListener("click", function() {
    document.getElementById("plugin-config-row").classList.toggle("active",true);
  });

  document.getElementById("plugin-input-finder-btn").addEventListener("click", function() {
    document.getElementById("plugin-metadata-inputs-row").classList.toggle("active",true);
  });

  document.getElementById("plugin-input-finder-submit").addEventListener("click", function() {
    document.getElementById("plugin-metadata-inputs-row").classList.toggle("active",false);
  });

  document.getElementById("plugin-config-submit").addEventListener("click", function() {
    document.getElementById("plugin-outputs-row").classList.toggle("active",true);
  });

  document.getElementById("generate-manifest-btn").addEventListener("click", function() {
    // Content of your YAML file
    const yamlContent = `
    name: My Manifest File
    description: My First Manifest File 💚
    initialize:
      outputs: ['yaml']
      plugins:
        group-by:
          path: 'builtin'
          method: GroupBy
        operational-carbon:
          path: '@grnsft/if-plugins'
          method: Multiply
          global-config:
            input-parameters: ['cpu/energy', 'grid/carbon-intensity']
            output-parameter: 'carbon'
        watttime:
          path: '@grnsft/if-unofficial-plugins'
          method: WattTimeGridEmissions
        teads-curve:
          path: '@grnsft/if-unofficial-plugins'
          method: TeadsCurve
          global-config:
            interpolation: spline
        cloud-metadata:
          method: CloudMetadata
          path: "@grnsft/if-plugins"
        mock-observations:
          path: '@grnsft/if-plugins'
          method: MockObservations
          global-config:
            timestamp-from: '2024-03-05T00:00:00.000Z'
            timestamp-to: '2024-03-05T00:01:00.000Z'
            duration: 10
            components:
              - name: server-1
                cloud/instance-type: Standard_E64_v3
                cloud/region: westus3
              - name: server-2
                cloud/instance-type: Standard_E64_v3
                cloud/region: westus3
            generators:
              common:
                cloud/vendor: azure
              randint:
                cpu/utilization:
                  min: 1
                  max: 99
        'time-sync':
          method: TimeSync
          path: "builtin"
          global-config:
            start-time: '2024-03-05T00:00:00.000Z'
            end-time: '2024-03-05T00:01:00.000Z'
            interval: 5
            allow-padding: true
    tree:
      pipeline:
        - mock-observations #provides sample usage data from a given geographic region with a simulated cpu / memory utilization.
        - group-by #groups inputs, in this case cloud and region
        - time-sync #standardizes the time format of observations
        - cloud-metadata #determine an instance's physical processor and thermal design power (TDP) based on its instance name (cloud vendor e.g. aws and instance type e.g. m5.large)
        - watttime #determine the carbon intensity of the grid based on the region (e.g. CAISO)
        - teads-curve #estimating CPU usages across varying type of CPUs using a Teads Curve (requires CPU TDP, Utilization, and Duration)
        - operational-carbon #combines two or more elements in an array, in this case energy in kWH and grid carbon intensity)
      defaults:
      config:
        group-by:
          group:
            - cloud/region
            - name
      inputs: null
    `;

    // Create a Blob object from the YAML content
    const blob = new Blob([yamlContent], { type: "text/yaml" });

    // Create a temporary anchor element
    const a = document.createElement("a");
    const url = window.URL.createObjectURL(blob);

    // Set the attributes for downloading
    a.href = url;
    a.download = "data.yaml";

    // Programmatically click the anchor element to initiate download
    a.click();

    // Clean up resources
    window.URL.revokeObjectURL(url);
    //document.body.removeChild(element);
  });

}
"""

css = """
.plugin-accordion button span:first-child {
    font-size: 1.25rem !important;
}

.dependent-row {
  display: none !important;
}

.dependent-row.active {
  display: block !important;
}
"""

def populate_plugin_inputs():
  return [gr.Dropdown(["Select Vendor","AWS","GCP","Azure","Other"], label="Cloud Vendor", info="Where is your data hosted?",interactive=True,value="AWS",elem_id="plugin_input_1",elem_classes=["dropdown-one-option"]), gr.Dropdown(["Select Instance","C5 Metal","d3.xlarge","m5.large"], label="Cloud Instance", info="Wnat cloud instance is your server using?",interactive=False,value="m5.large",elem_classes=["dependent-dropdown"],elem_id="plugin_input_2"),gr.Button("Help me find my inputs", elem_id="plugin-input-finder-btn",visible=False)]

def populate_plugin_input_1():
  return gr.Dropdown(["Select Vendor","AWS","GCP","Azure","Other"], label="Cloud Vendor", info="Where is your data hosted?",interactive=True,value="AWS",elem_id="plugin_input_1",elem_classes=["dropdown-one-option"])

def populate_plugin_input_2():
  return gr.Dropdown(["Select Instance","C5 Metal","d3.xlarge","m5.large"], label="Cloud Instance", info="Wnat cloud instance is your server using?",interactive=False,value="m5.large",elem_classes=["dependent-dropdown"],elem_id="plugin_input_2")

with gr.Blocks(css=css,js=js) as pipeline_builder:
  gr.Markdown("# 🚰 Impact Framework Pipeline Builder")
  gr.Markdown("Visually construct your Impact Framework manifest file pipeline with this helpful interface.")

  with gr.Accordion("ℹ️ About this Page",open=False,elem_classes=["plugin-accordion"]):
    gr.Markdown("### Why is this tool needed?")
    gr.Markdown("Currently, it can be hard to know where to find the right plugins for your pipeline, what they do, and how to configure them for your specific software workload.")
    gr.Markdown("### What does this tool do?")
    gr.Markdown("This is a prototype of a visual interface that would walk you step by step through constructing an IF pipeline, helping you to find the specific configuration values your software uses, and providing you with sample outputs to help you determine what plugin you need next.")

  with gr.Row(elem_id="plugin-selector-row",variant="panel"):
    with gr.Column():
      with gr.Row():
        gr.Markdown("## Find Your Plugin")
      with gr.Row():
        plugin_selector = gr.Dropdown(["Watt-Time","CO2.js","TDP Finder","Cloud Metadata"], label="Plugin",value="Cloud Metadata",interactive=True,info="Plugins available on the Impact Framework Registry")
      with gr.Row():
        plugin_selector_submit = gr.Button("Configure Plugin",elem_id="plugin-selector-submit")

  with gr.Row(elem_classes=["dependent-row"],elem_id="plugin-config-row", variant="panel"):
    with gr.Column():
      with gr.Row():
        gr.Markdown("## Configure Your Plugin")
      with gr.Row():
        gr.Markdown("### Cloud Metadata")
      with gr.Row(variant="panel"):
        plugin_input_1 = gr.Dropdown(["Select Vendor","AWS","GCP","Azure","Other"], label="Cloud Vendor", info="Where is your data hosted?",interactive=True,value="Select Vendor",elem_id="plugin_input_1",elem_classes=["dropdown-one-option"])
        plugin_input_2 = gr.Dropdown(["Select Instance","C5 Metal","d3.xlarge","m5.large"], label="Cloud Instance", info="Wnat cloud instance is your server using?",interactive=True,value="Select Instance",elem_classes=["dependent-dropdown"],elem_id="plugin_input_2")
      with gr.Row():
        plugin_input_finder_btn = gr.Button("Help me find my inputs", elem_id="plugin-input-finder-btn")
        plugin_config_submit = gr.Button("Submit configuration",variant="primary",elem_id="plugin-config-submit")



  with gr.Row(elem_classes=["dependent-row"],elem_id="plugin-metadata-inputs-row", variant="panel"):
    with gr.Row():
      gr.Markdown("## Find your Cloud Metadata inputs")
    with gr.Row():
      plugin_input_finder_url = gr.Textbox(placeholder="https://[your_website.com]", label="Your website URL", info="If you are measuring energy based on a hosted website, enter the URL",value="https://mywebsite.com",interactive=False)
    with gr.Row():
      plugin_input_finder_submit = gr.Button("Find Inputs",elem_id="plugin-input-finder-submit")

  with gr.Row(elem_classes=["dependent-row"],elem_id="plugin-outputs-row", variant="panel"):
    with gr.Column():
      with gr.Row():
        gr.Markdown("## Sample plugin outputs")
      with gr.Row():
        gr.Markdown("This is data you can expect to see in the output from the plugin.")
      with gr.Row():
        gr.Markdown("#### CPU/TDP")
      with gr.Row(variant="panel"):
        gr.Textbox(value=270,label="Amount")
        gr.Textbox(value="Watts",label="Units")
        gr.Textbox(value="CPU/GPU Heat Dissipation",label="ℹ️")

      with gr.Row():
        gr.Markdown("#### Memory")
      with gr.Row(variant="panel"):
        gr.Textbox(value=432,label="Amount")
        gr.Textbox(value="GB",label="Units")
      with gr.Row():
        gr.Markdown("#### Processor")
      with gr.Row(variant="panel"):
        gr.Textbox(value="Intel XEON 830C",label="type")
      with gr.Row():
        gr.Markdown("#### VCPUs")
      with gr.Row(variant="panel"):
        gr.Textbox(value="64 / 64",label="used / available")

      with gr.Row(elem_id="plugin-add-submit-row", variant="panel"):
        gr.Button("Add Another Plugin",variant="secondary",interactive=False)
        generate_manifest_btn = gr.Button("Generate Manifest",variant="primary",elem_id="generate-manifest-btn")

  plugin_input_finder_submit.click(fn=populate_plugin_inputs, outputs=[plugin_input_1,plugin_input_2,plugin_input_finder_btn])
  plugin_config_submit.click(fn=populate_plugin_inputs, outputs=[plugin_input_1,plugin_input_2,plugin_input_finder_btn])


pipeline_builder.launch()