Skip to content
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

[Interchange] Exports DeviceResources Routing (Wires and Nodes) Info in Multiple Messages #1017

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
27 changes: 18 additions & 9 deletions src/com/xilinx/rapidwright/interchange/DeviceResourcesExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,28 @@
public class DeviceResourcesExample {

public static final String SKIP_ROUTE_RESOURCES_OPTION = "--skip_route_resources";
public static final String VERIFY_OPTION = "--verify";

public static void main(String[] args) throws IOException {
if (args.length != 1 && args.length != 2) {
System.out.println("USAGE: <device name> [" + SKIP_ROUTE_RESOURCES_OPTION + "]");
if (args.length < 1 || args.length > 3) {
System.out.println("USAGE: <device name> [" + SKIP_ROUTE_RESOURCES_OPTION + "] [" + VERIFY_OPTION + "]");
System.out.println(" Example dump of device information for interchange format.");
return;
}

boolean skipRouteResources = false;
if (args.length == 2 && args[1].equals(SKIP_ROUTE_RESOURCES_OPTION)) {
skipRouteResources = true;
boolean verify = false;
for (int i = 1; i < args.length; i++) {
if (args[i].equals(SKIP_ROUTE_RESOURCES_OPTION)) {
skipRouteResources = true;
} else if (args[i].equals(VERIFY_OPTION)) {
verify = true;
}
}

CodePerfTracker t = new CodePerfTracker("Device Resources Dump: " + args[0]);
t.useGCToTrackMemory(true);
t.setReportingCurrOSMemUsage(true);
t.setTrackOSMemUsage(true);

// Create device resource file if it doesn't exist
String capnProtoFileName = args[0] + ".device";
Expand All @@ -56,10 +63,12 @@ public static void main(String[] args) throws IOException {
DeviceResourcesWriter.writeDeviceResourcesFile(args[0], device, t, capnProtoFileName, skipRouteResources);
Device.releaseDeviceReferences();

t.start("Verify file");
// Verify device resources
DeviceResourcesVerifier.verifyDeviceResources(capnProtoFileName, args[0]);
if (verify) {
// Verify device resources
DeviceResourcesVerifier.verifyDeviceResources(capnProtoFileName, args[0], t);
}

t.stop().printSummary();
t.printSummary();
System.out.println("Device resources file '" + capnProtoFileName + "' written successfully");
}
}
100 changes: 93 additions & 7 deletions src/com/xilinx/rapidwright/interchange/DeviceResourcesVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@

package com.xilinx.rapidwright.interchange;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.channels.ReadableByteChannel;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -55,6 +59,7 @@
import com.xilinx.rapidwright.device.Device;
import com.xilinx.rapidwright.device.Grade;
import com.xilinx.rapidwright.device.IOStandard;
import com.xilinx.rapidwright.device.Node;
import com.xilinx.rapidwright.device.PIP;
import com.xilinx.rapidwright.device.PIPType;
import com.xilinx.rapidwright.device.Package;
Expand All @@ -66,6 +71,7 @@
import com.xilinx.rapidwright.device.SiteTypeEnum;
import com.xilinx.rapidwright.device.Tile;
import com.xilinx.rapidwright.device.TileTypeEnum;
import com.xilinx.rapidwright.device.Wire;
import com.xilinx.rapidwright.edif.EDIFCell;
import com.xilinx.rapidwright.edif.EDIFCellInst;
import com.xilinx.rapidwright.edif.EDIFDesign;
Expand All @@ -90,6 +96,7 @@
import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist;
import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Direction;
import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.PropertyMap;
import com.xilinx.rapidwright.tests.CodePerfTracker;
import com.xilinx.rapidwright.util.Pair;

public class DeviceResourcesVerifier {
Expand Down Expand Up @@ -130,7 +137,9 @@ private static void verifyBelPin(StructList.Reader<DeviceResources.Device.BELPin
expect(pin.getBEL().getName(), allStrings.get(belPin.getBel()));
}

public static boolean verifyDeviceResources(String devResFileName, String deviceName) throws IOException {
public static boolean verifyDeviceResources(String devResFileName, String deviceName, CodePerfTracker t)
throws IOException {
t.start("*Verify Init");
allStrings = new StringEnumerator();
verifiedSiteTypes = new HashSet<SiteTypeEnum>();

Expand All @@ -143,11 +152,13 @@ public static boolean verifyDeviceResources(String devResFileName, String device
DeviceResources.Device.Reader dReader = null;
ReaderOptions readerOptions = new ReaderOptions(1024L * 1024L * 1024L * 64L, 64);
MessageReader readMsg = null;
readMsg = Interchange.readInterchangeFile(devResFileName, readerOptions);
ReadableByteChannel rbc = Interchange.getReadableByteChannel(devResFileName);

readMsg = Interchange.readMessageFromChannel(rbc, readerOptions);

dReader = readMsg.getRoot(DeviceResources.Device.factory);

boolean containsRoutingResources = dReader.getNodes().size() > 0;
boolean containsMultiMessageRoutingResources = !dReader.hasNodes();

int strCount = dReader.getStrList().size();
TextList.Reader reader = dReader.getStrList();
Expand All @@ -156,6 +167,8 @@ public static boolean verifyDeviceResources(String devResFileName, String device
allStrings.addObject(str);
}

t.stop().start("*Verify Tiles & Sites");

// Create a lookup map for tile types
Map<String,TileType.Reader> tileTypeMap = new HashMap<String, TileType.Reader>();
Map<TileTypeEnum, TileType.Reader> tileTypeEnumMap = new HashMap<TileTypeEnum, TileType.Reader>();
Expand Down Expand Up @@ -477,13 +490,15 @@ public static boolean verifyDeviceResources(String devResFileName, String device
}
}

t.stop().start("*Verify Libraries");

Netlist.Reader primLibs = dReader.getPrimLibs();
LogNetlistReader netlistReader = new LogNetlistReader(allStrings, new HashMap<String, String>() {{
put(LogNetlistWriter.DEVICE_PRIMITIVES_LIB, EDIFTools.EDIF_LIBRARY_HDI_PRIMITIVES_NAME);
}}
);
EDIFNetlist primsAndMacros = netlistReader.readLogNetlist(primLibs,
/*skipTopStuff=*/true, /*expandMacros=*/false);
/* skipTopStuff= */true, /* expandMacros= */false, CodePerfTracker.SILENT);

Set<String> libsFound = new HashSet<String>();
libsFound.addAll(primsAndMacros.getLibrariesMap().keySet());
Expand Down Expand Up @@ -617,16 +632,87 @@ public static boolean verifyDeviceResources(String devResFileName, String device
}
}

t.stop().start("*Verify CellBelPins");
verifyCellBelPinMaps(allStrings, dReader, design);
t.stop().start("*Verify Packages");
verifyPackages(allStrings, dReader, device);

if (containsRoutingResources) {
ConstantDefinitions.verifyConstants(allStrings, device, design, siteTypes, dReader.getConstants(), tileTypeEnumMap);
t.stop();

if (containsMultiMessageRoutingResources) {
t.start("*Verify Constants");
ConstantDefinitions.verifyConstants(allStrings, device, design, siteTypes,
dReader.getConstants(), tileTypeEnumMap);
t.stop().start("*Verify Nodes & Wires");
verifyWireAndNodeMultiMessage(device, allStrings, rbc, readerOptions);
t.stop();
}


rbc.close();
return true;
}

private static void verifyWireAndNodeMultiMessage(Device device, StringEnumerator allStrings,
ReadableByteChannel rbc, ReaderOptions options) {
int numOfMessages = device.getRows();

for (int row = 0; row < numOfMessages; row++) {
LongEnumerator allWires = new LongEnumerator();
DeviceResources.Device.Reader deviceReader = null;
try {
MessageReader mReader = Interchange.readMessageFromChannel(rbc, options);
deviceReader = mReader.getRoot(DeviceResources.Device.factory);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
StructList.Reader<DeviceResources.Device.Wire.Reader> wires = deviceReader.getWires();
StructList.Reader<DeviceResources.Device.Node.Reader> nodeList = deviceReader.getNodes();

int wireIdx = 0;
int nodeIdx = 0;
for (Tile tile : device.getTiles()[row]) {
for (int i = 0; i < tile.getWireCount(); i++) {
Node node = Node.getNode(tile, i);
if (node == null) {
long nodeWireKey = DeviceResourcesWriter.makeKey(tile, i);
Integer test = allWires.maybeGetIndex(nodeWireKey);
if (test == null) {
allWires.addObject(nodeWireKey);
DeviceResources.Device.Wire.Reader readWire = wires.get(wireIdx++);
expect(tile.getName(), allStrings.get(readWire.getTile()));
expect(tile.getWireName(i), allStrings.get(readWire.getWire()));
expect(tile.getWireIntentCode(i).ordinal(), readWire.getType());
}
}else if (node.getTile() == tile && node.getWireIndex() == i) {
Wire[] nodeWires = node.getAllWiresInNode();
for (Wire w : nodeWires) {
long nodeWireKey = DeviceResourcesWriter.makeKey(w.getTile(), w.getWireIndex());
Integer test = allWires.maybeGetIndex(nodeWireKey);
if (test == null) {
allWires.addObject(nodeWireKey);
DeviceResources.Device.Wire.Reader readWire = wires.get(wireIdx++);
expect(w.getTile().getName(), allStrings.get(readWire.getTile()));
expect(w.getWireName(), allStrings.get(readWire.getWire()));
expect(w.getIntentCode().ordinal(), readWire.getType());
}
}
DeviceResources.Device.Node.Reader readNode = nodeList.get(nodeIdx++);
PrimitiveList.Int.Reader readNodeWires = readNode.getWires();
expect(nodeWires.length, readNodeWires.size());
for (int j = 0; j < nodeWires.length; j++) {
int wireKey = readNodeWires.get(j);
Long wireEntry = allWires.get(wireKey);
int tIdx = (int) (wireEntry >>> 32);
int wIdx = (int) (wireEntry & 0xFFFFFFFF);
expect(nodeWires[j].getTile().getUniqueAddress(), tIdx);
expect(nodeWires[j].getWireIndex(), wIdx);
}
}
}
}
}
}


private static HashSet<SiteTypeEnum> verifiedSiteTypes;

Expand Down
89 changes: 83 additions & 6 deletions src/com/xilinx/rapidwright/interchange/DeviceResourcesWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
package com.xilinx.rapidwright.interchange;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -297,10 +299,17 @@ public static void writeDeviceResourcesFile(String part, Device device, CodePerf
t.stop().start("Tiles");
writeAllTilesToBuilder(device, devBuilder, tileTypeIndicies);

t.stop().start("Wires&Nodes");
writeAllWiresAndNodesToBuilder(device, devBuilder, skipRouteResources);
if (skipRouteResources) {
// Let's set wires and nodes to size 0
devBuilder.initWires(0);
devBuilder.initNodes(0);
} else {
// We'll add them as multiple messages after the main device message, one row of
// tiles' worth of wires and nodes at a time. We'll leave the wires and node
// field as an indicator that more messages will be present.
}

t.stop().start("Prims&Macros");
t.stop().start("Prims & Macros");
// Create an EDIFNetlist populated with just primitive and macro libraries
EDIFLibrary prims = Design.getPrimitivesLibrary(device.getName());
EDIFLibrary macros = Design.getMacroPrimitives(series);
Expand Down Expand Up @@ -469,8 +478,15 @@ public static void writeDeviceResourcesFile(String part, Device device, CodePerf
t.stop().start("Strings");
writeAllStringsToBuilder(devBuilder);

t.stop().start("Write File");
Interchange.writeInterchangeFile(fileName, message);
t.stop().start("Write Device (single message)");
WritableByteChannel wbc = Interchange.getWritableByteChannel(fileName);
Interchange.writeMessageToChannel(wbc, message);

if (!skipRouteResources) {
t.stop().start("Write Wires & Nodes (multi-message)");
writeAllWiresAndNodesToMultipleMessages(device, wbc);
}
wbc.close();
t.stop();
}

Expand Down Expand Up @@ -809,12 +825,72 @@ public static void writeAllTilesToBuilder(Device device, DeviceResources.Device.

}

private static long makeKey(Tile tile, int wire) {
protected static long makeKey(Tile tile, int wire) {
long key = wire;
key = (((long)tile.getUniqueAddress()) << 32) | key;
return key;
}

public static void writeAllWiresAndNodesToMultipleMessages(Device device, WritableByteChannel wbc) {
// Write one message for each row of tiles in the device
int numOfMessages = device.getRows();

for (int m = 0; m < numOfMessages; m++) {
MessageBuilder message = new MessageBuilder();
DeviceResources.Device.Builder devBuilder = message.initRoot(DeviceResources.Device.factory);

LongEnumerator allWires = new LongEnumerator();
ArrayList<Long> allNodes = new ArrayList<>();

for (Tile tile : device.getTiles()[m]) {
for (int i = 0; i < tile.getWireCount(); i++) {
Node node = Node.getNode(tile, i);
if (node == null) {
allWires.addObject(makeKey(tile, i));
} else if (node.getTile() == tile && node.getWireIndex() == i) {
allNodes.add(makeKey(node.getTile(), node.getWireIndex()));
Wire[] nodeWires = node.getAllWiresInNode();
for (Wire w : nodeWires) {
allWires.addObject(makeKey(w.getTile(), w.getWireIndex()));
}
}
}
}

StructList.Builder<DeviceResources.Device.Wire.Builder> wireBuilders = devBuilder
.initWires(allWires.size());

for (int i = 0; i < allWires.size(); i++) {
DeviceResources.Device.Wire.Builder wireBuilder = wireBuilders.get(i);
long wireKey = allWires.get(i);
Wire wire = new Wire(device.getTile((int) (wireKey >>> 32)), (int) (wireKey & 0xffffffff));
// Wire wire = allWires.get(i);
wireBuilder.setTile(allStrings.getIndex(wire.getTile().getName()));
wireBuilder.setWire(allStrings.getIndex(wire.getWireName()));
wireBuilder.setType(wire.getIntentCode().ordinal());
}

StructList.Builder<DeviceResources.Device.Node.Builder> nodeBuilders = devBuilder
.initNodes(allNodes.size());
for (int i = 0; i < allNodes.size(); i++) {
DeviceResources.Device.Node.Builder nodeBuilder = nodeBuilders.get(i);
long nodeKey = allNodes.get(i);
Node node = Node.getNode(device.getTile((int) (nodeKey >>> 32)), (int) (nodeKey & 0xffffffff));
Wire[] wires = node.getAllWiresInNode();
PrimitiveList.Int.Builder wBuilders = nodeBuilder.initWires(wires.length);
for (int k = 0; k < wires.length; k++) {
wBuilders.set(k, allWires.maybeGetIndex(makeKey(wires[k].getTile(), wires[k].getWireIndex())));
}
}

try {
Interchange.writeMessageToChannel(wbc, message);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}

public static void writeAllWiresAndNodesToBuilder(Device device, DeviceResources.Device.Builder devBuilder,
boolean skipRouteResources) {
LongEnumerator allWires = new LongEnumerator();
Expand Down Expand Up @@ -862,6 +938,7 @@ public static void writeAllWiresAndNodesToBuilder(Device device, DeviceResources
}
}
}

private static void populatePackages(StringEnumerator allStrings, Device device, DeviceResources.Device.Builder devBuilder) {
Set<String> packages = device.getPackages();
List<String> packagesList = new ArrayList<String>();
Expand Down
Loading
Loading