Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.autotune.analyzer.adapters;

import com.autotune.analyzer.recommendations.AcceleratorRecommendationItem;
import com.autotune.analyzer.recommendations.MultiResourceRecommendation;
import com.google.gson.*;
import java.lang.reflect.Type;
import java.util.List;

/**
* Serializes MultiResourceRecommendation as array (unwraps the wrapper)
*/
public class MultiResourceRecommendationAdapter
implements JsonSerializer<MultiResourceRecommendation>, JsonDeserializer<MultiResourceRecommendation> {

@Override
public JsonElement serialize(MultiResourceRecommendation src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src.getItems());
}

@Override
public MultiResourceRecommendation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Deserialization does not guard against non-array or null JSON and may produce a MultiResourceRecommendation with a null items list.

The adapter currently assumes json can always be deserialized into List<AcceleratorRecommendationItem> and passes that (possibly null) list to the constructor. Consider:

  • Returning an empty MultiResourceRecommendation when json is null or JsonNull.
  • Validating that json is a JsonArray and throwing a clear JsonParseException otherwise.
    This will keep items non-null and make failures more explicit and predictable.

Suggested implementation:

    @Override
    public MultiResourceRecommendation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        // Treat null or JsonNull as an empty recommendation rather than returning a null items list
        if (json == null || json.isJsonNull()) {
            return new MultiResourceRecommendation(Collections.emptyList());
        }

        // Ensure the JSON structure is an array; fail fast with a clear error otherwise
        if (!json.isJsonArray()) {
            throw new JsonParseException(
                    "Expected a JSON array for MultiResourceRecommendation, but found: " + json.toString());
        }

        Type listType = new com.google.gson.reflect.TypeToken<List<AcceleratorRecommendationItem>>() {}.getType();
        List<AcceleratorRecommendationItem> items = context.deserialize(json, listType);

        // Guarantee items is non-null
        if (items == null) {
            items = Collections.emptyList();
        }

        return new MultiResourceRecommendation(items);
    }

To compile successfully, ensure the following import is present at the top of the file (if not already there):

  • import java.util.Collections;

If it is missing, add it alongside the other imports in this class.

throws JsonParseException {
Type listType = new com.google.gson.reflect.TypeToken<List<AcceleratorRecommendationItem>>(){}.getType();
List<AcceleratorRecommendationItem> items = context.deserialize(json, listType);
return new MultiResourceRecommendation(items);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.autotune.analyzer.recommendations;

public class AcceleratorRecommendationItem implements ResourceRecommendation {
private String model;
private String partition;
private Integer count;
private RecommendationConfigItem compute;
private RecommendationConfigItem memory;

public AcceleratorRecommendationItem(String model, String partition, Integer count, RecommendationConfigItem compute, RecommendationConfigItem memory) {
this.model = model;
this.partition = partition;
this.count = count;
this.compute = compute;
this.memory = memory;
}

public String getModel() {
return model;
}

public String getPartition() {
return partition;
}

public Integer getCount() {
return count;
}

public RecommendationConfigItem getCompute() {
return compute;
}

public RecommendationConfigItem getMemory() {
return memory;
}
}
12 changes: 6 additions & 6 deletions src/main/java/com/autotune/analyzer/recommendations/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@
import java.util.Map;

public class Config {
private Map<AnalyzerConstants.RecommendationItem, RecommendationConfigItem> requests;
private Map<AnalyzerConstants.RecommendationItem, RecommendationConfigItem> limits;
private Map<AnalyzerConstants.RecommendationItem, ResourceRecommendation> requests;
private Map<AnalyzerConstants.RecommendationItem, ResourceRecommendation> limits;
private List<RecommendationConfigEnv> env;

public Map<AnalyzerConstants.RecommendationItem, RecommendationConfigItem> getRequests() {
public Map<AnalyzerConstants.RecommendationItem, ResourceRecommendation> getRequests() {
return requests;
}

public void setRequests(Map<AnalyzerConstants.RecommendationItem, RecommendationConfigItem> requests) {
public void setRequests(Map<AnalyzerConstants.RecommendationItem, ResourceRecommendation> requests) {
this.requests = requests;
}

public Map<AnalyzerConstants.RecommendationItem, RecommendationConfigItem> getLimits() {
public Map<AnalyzerConstants.RecommendationItem, ResourceRecommendation> getLimits() {
return limits;
}

public void setLimits(Map<AnalyzerConstants.RecommendationItem, RecommendationConfigItem> limits) {
public void setLimits(Map<AnalyzerConstants.RecommendationItem, ResourceRecommendation> limits) {
this.limits = limits;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.autotune.analyzer.recommendations;

import com.autotune.analyzer.adapters.MultiResourceRecommendationAdapter;
import com.google.gson.annotations.JsonAdapter;
import java.util.ArrayList;
import java.util.List;

/**
* Represents multiple resource recommendations (Accelerators array)
* Custom adapter ensures it serializes as array, not object
*/
@JsonAdapter(MultiResourceRecommendationAdapter.class)
public final class MultiResourceRecommendation implements ResourceRecommendation {
private List<AcceleratorRecommendationItem> items;

public MultiResourceRecommendation() {
this.items = new ArrayList<>();
}

public MultiResourceRecommendation(List<AcceleratorRecommendationItem> items) {
this.items = items;
}

public List<AcceleratorRecommendationItem> getItems() {
return items;
}

public void setItems(List<AcceleratorRecommendationItem> items) {
this.items = items;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*******************************************************************************/
package com.autotune.analyzer.recommendations;

public class RecommendationConfigItem {
public class RecommendationConfigItem implements ResourceRecommendation {
private Double amount;
private String format;
private String errorMsg;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.autotune.analyzer.recommendations;

public interface ResourceRecommendation {
}
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ public boolean populateRecommendation(Map.Entry<String, Terms> termEntry,

Config config = new Config();
// Create Request Map
HashMap<AnalyzerConstants.RecommendationItem, RecommendationConfigItem> requestsMap = new HashMap<>();
HashMap<AnalyzerConstants.RecommendationItem, ResourceRecommendation> requestsMap = new HashMap<>();
// Recommendation Item checks
boolean isCpuRequestValid = true;
boolean isMemoryRequestValid = true;
Expand Down Expand Up @@ -668,7 +668,7 @@ public boolean populateRecommendation(Map.Entry<String, Terms> termEntry,
}

// Create Limits Map
HashMap<AnalyzerConstants.RecommendationItem, RecommendationConfigItem> limitsMap = new HashMap<>();
HashMap<AnalyzerConstants.RecommendationItem, ResourceRecommendation> limitsMap = new HashMap<>();
// Recommendation Item checks (adding additional check for limits even though they are same as limits to maintain code to be flexible to add limits in future)
boolean isCpuLimitValid = true;
boolean isMemoryLimitValid = true;
Expand Down Expand Up @@ -903,7 +903,7 @@ public boolean populateRecommendation(Map.Entry<String, Terms> termEntry,

// Alternative - CPU REQUEST VALUE
// Accessing existing recommendation item
RecommendationConfigItem tempAccessedRecCPURequest = requestsMap.get(AnalyzerConstants.RecommendationItem.CPU);
RecommendationConfigItem tempAccessedRecCPURequest = (RecommendationConfigItem) requestsMap.get(AnalyzerConstants.RecommendationItem.CPU);
if (null != tempAccessedRecCPURequest) {
// Updating it with desired value
tempAccessedRecCPURequest.setAmount(currentCpuRequestValue);
Expand Down Expand Up @@ -943,7 +943,7 @@ public boolean populateRecommendation(Map.Entry<String, Terms> termEntry,

// Alternative - CPU LIMIT VALUE
// Accessing existing recommendation item
RecommendationConfigItem tempAccessedRecCPULimit = limitsMap.get(AnalyzerConstants.RecommendationItem.CPU);
RecommendationConfigItem tempAccessedRecCPULimit = (RecommendationConfigItem) limitsMap.get(AnalyzerConstants.RecommendationItem.CPU);
if (null != tempAccessedRecCPULimit) {
// Updating it with desired value
tempAccessedRecCPULimit.setAmount(currentCpuLimitValue);
Expand Down Expand Up @@ -983,7 +983,7 @@ public boolean populateRecommendation(Map.Entry<String, Terms> termEntry,

// Alternative - MEMORY REQUEST VALUE
// Accessing existing recommendation item
RecommendationConfigItem tempAccessedRecMemoryRequest = requestsMap.get(AnalyzerConstants.RecommendationItem.MEMORY);
RecommendationConfigItem tempAccessedRecMemoryRequest = (RecommendationConfigItem) requestsMap.get(AnalyzerConstants.RecommendationItem.MEMORY);
if (null != tempAccessedRecMemoryRequest) {
// Updating it with desired value
tempAccessedRecMemoryRequest.setAmount(currentMemRequestValue);
Expand Down Expand Up @@ -1023,7 +1023,7 @@ public boolean populateRecommendation(Map.Entry<String, Terms> termEntry,

// Alternative - MEMORY LIMIT VALUE
// Accessing existing recommendation item
RecommendationConfigItem tempAccessedRecMemoryLimit = limitsMap.get(AnalyzerConstants.RecommendationItem.MEMORY);
RecommendationConfigItem tempAccessedRecMemoryLimit = (RecommendationConfigItem) limitsMap.get(AnalyzerConstants.RecommendationItem.MEMORY);
if (null != tempAccessedRecMemoryLimit) {
// Updating it with desired value
tempAccessedRecMemoryLimit.setAmount(currentMemLimitValue);
Expand Down
Loading