mirror of https://github.com/openXC7/prjxray.git
Fuzzer 074 Multi Thread optimisation
Signed-off-by: Mehdi Khairy <mehdi.khairy@more-magic.org>
This commit is contained in:
parent
748580a1f2
commit
9f4c26c280
|
|
@ -2,6 +2,9 @@
|
|||
N := 1
|
||||
SPECIMENS := $(addprefix build/specimen_,$(shell seq -f '%03.0f' $(N)))
|
||||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||
MAX_VIVADO_PROCESS ?= 4
|
||||
MAX_TILES_INSTANCE ?= 300
|
||||
MAX_NODES_INSTANCE ?= 30000
|
||||
|
||||
database: $(SPECIMENS_OK)
|
||||
true
|
||||
|
|
@ -13,7 +16,7 @@ pushdb:
|
|||
cp build/output/tileconn.json ${XRAY_DATABASE_DIR}/$(XRAY_DATABASE)/
|
||||
|
||||
$(SPECIMENS_OK):
|
||||
bash generate.sh $(subst /OK,,$@)
|
||||
bash generate.sh $(subst /OK,,$@) -p=$(MAX_VIVADO_PROCESS) -t=$(MAX_TILES_INSTANCE) -n=$(MAX_NODES_INSTANCE)
|
||||
touch $@
|
||||
|
||||
run:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
source ${XRAY_GENHEADER}
|
||||
|
||||
${XRAY_VIVADO} -mode batch -source $FUZDIR/generate.tcl
|
||||
python3 $FUZDIR/run_fuzzer.py $2 $3 $4
|
||||
|
||||
cd $FUZDIR && ./generate_after_dump.sh
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
create_project -force -part $::env(XRAY_PART) design design
|
||||
set_property design_mode PinPlanning [current_fileset]
|
||||
open_io_design -name io_1
|
||||
|
||||
#set_param tcl.collectionResultDisplayLimit 0
|
||||
set_param messaging.disableStorage 1
|
||||
|
||||
set nbnodes_fp [open nb_nodes.txt w]
|
||||
|
||||
set nodes [get_nodes]
|
||||
puts $nbnodes_fp [llength $nodes]
|
||||
|
||||
close $nbnodes_fp
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
create_project -force -part $::env(XRAY_PART) design design
|
||||
set_property design_mode PinPlanning [current_fileset]
|
||||
open_io_design -name io_1
|
||||
|
||||
#set_param tcl.collectionResultDisplayLimit 0
|
||||
set_param messaging.disableStorage 1
|
||||
|
||||
set nbtiles_fp [open nb_tiles.txt w]
|
||||
|
||||
set tiles [get_tiles]
|
||||
puts $nbtiles_fp [llength $tiles]
|
||||
|
||||
close $nbtiles_fp
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
set blocknb [lindex $argv 0]
|
||||
set start [expr int([lindex $argv 1])]
|
||||
set stop [expr int([lindex $argv 2])]
|
||||
|
||||
create_project -force -part $::env(XRAY_PART) $blocknb $blocknb
|
||||
set_property design_mode PinPlanning [current_fileset]
|
||||
open_io_design -name io_1
|
||||
|
||||
#set_param tcl.collectionResultDisplayLimit 0
|
||||
set_param messaging.disableStorage 1
|
||||
|
||||
set root_fp [open "root_node_${blocknb}.csv" w]
|
||||
|
||||
set nodes [get_nodes]
|
||||
|
||||
for {set j $start } { $j < $stop } { incr j } {
|
||||
|
||||
set node [lindex $nodes $j]
|
||||
|
||||
file mkdir [file dirname "${node}"]
|
||||
set fname $node.json5
|
||||
puts $root_fp "node,,$fname"
|
||||
|
||||
set fp [open "${fname}" w]
|
||||
# node properties:
|
||||
# BASE_CLOCK_REGION CLASS COST_CODE COST_CODE_NAME IS_BAD IS_COMPLETE
|
||||
# IS_GND IS_INPUT_PIN IS_OUTPUT_PIN IS_PIN IS_VCC NAME NUM_WIRES PIN_WIRE
|
||||
# SPEED_CLASS
|
||||
puts $fp "\{"
|
||||
puts $fp "\t\"node\": \"$node\","
|
||||
puts $fp "\t\"wires\": \["
|
||||
foreach wire [get_wires -of_objects $node] {
|
||||
# wire properties:
|
||||
# CLASS COST_CODE ID_IN_TILE_TYPE IS_CONNECTED IS_INPUT_PIN IS_OUTPUT_PIN
|
||||
# IS_PART_OF_BUS NAME NUM_DOWNHILL_PIPS NUM_INTERSECTS NUM_PIPS
|
||||
# NUM_TILE_PORTS NUM_UPHILL_PIPS SPEED_INDEX TILE_NAME TILE_PATTERN_OFFSET
|
||||
puts $fp "\t\t\{"
|
||||
puts $fp "\t\t\t\"wire\":\"$wire\","
|
||||
puts $fp "\t\t\},"
|
||||
}
|
||||
puts $fp "\t\]"
|
||||
puts $fp "\}"
|
||||
close $fp
|
||||
}
|
||||
|
||||
close $root_fp
|
||||
|
|
@ -1,15 +1,28 @@
|
|||
create_project -force -part $::env(XRAY_PART) design design
|
||||
set blocknb [lindex $argv 0]
|
||||
set start [expr int([lindex $argv 1])]
|
||||
set stop [expr int([lindex $argv 2])]
|
||||
|
||||
create_project -force -part $::env(XRAY_PART) $blocknb $blocknb
|
||||
set_property design_mode PinPlanning [current_fileset]
|
||||
open_io_design -name io_1
|
||||
|
||||
set root_fp [open root.csv w]
|
||||
puts $root_fp "filetype,subtype,filename"
|
||||
foreach tile [get_tiles] {
|
||||
#set_param tcl.collectionResultDisplayLimit 0
|
||||
set_param messaging.disableStorage 1
|
||||
|
||||
set root_fp [open "root_${blocknb}.csv" w]
|
||||
#puts $root_fp "filetype,subtype,filename"
|
||||
|
||||
set tiles [get_tiles]
|
||||
|
||||
for {set j $start } { $j < $stop } { incr j } {
|
||||
|
||||
set tile [lindex $tiles $j]
|
||||
|
||||
set fname tile_$tile.json5
|
||||
set tile_type [get_property TYPE $tile]
|
||||
puts $root_fp "tile,$tile_type,$fname"
|
||||
|
||||
set fp [open $fname w]
|
||||
set fp [open "${fname}" w]
|
||||
puts $fp "\{"
|
||||
puts $fp "\t\"tile\": \"$tile\","
|
||||
# tile properties:
|
||||
|
|
@ -106,31 +119,4 @@ foreach tile [get_tiles] {
|
|||
close $fp
|
||||
}
|
||||
|
||||
foreach node [get_nodes] {
|
||||
file mkdir [file dirname $node]
|
||||
set fname $node.json5
|
||||
puts $root_fp "node,,$fname"
|
||||
|
||||
set fp [open $fname w]
|
||||
# node properties:
|
||||
# BASE_CLOCK_REGION CLASS COST_CODE COST_CODE_NAME IS_BAD IS_COMPLETE
|
||||
# IS_GND IS_INPUT_PIN IS_OUTPUT_PIN IS_PIN IS_VCC NAME NUM_WIRES PIN_WIRE
|
||||
# SPEED_CLASS
|
||||
puts $fp "\{"
|
||||
puts $fp "\t\"node\": \"$node\","
|
||||
puts $fp "\t\"wires\": \["
|
||||
foreach wire [get_wires -of_objects $node] {
|
||||
# wire properties:
|
||||
# CLASS COST_CODE ID_IN_TILE_TYPE IS_CONNECTED IS_INPUT_PIN IS_OUTPUT_PIN
|
||||
# IS_PART_OF_BUS NAME NUM_DOWNHILL_PIPS NUM_INTERSECTS NUM_PIPS
|
||||
# NUM_TILE_PORTS NUM_UPHILL_PIPS SPEED_INDEX TILE_NAME TILE_PATTERN_OFFSET
|
||||
puts $fp "\t\t\{"
|
||||
puts $fp "\t\t\t\"wire\":\"$wire\","
|
||||
puts $fp "\t\t\},"
|
||||
}
|
||||
puts $fp "\t\]"
|
||||
puts $fp "\}"
|
||||
close $fp
|
||||
}
|
||||
|
||||
close $root_fp
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import subprocess
|
||||
import signal
|
||||
from multiprocessing import Pool
|
||||
from itertools import chain
|
||||
import argparse
|
||||
|
||||
# Can be used to redirect vivado tons of output
|
||||
# stdout=DEVNULL in subprocess.check_call
|
||||
|
||||
|
||||
# Worker function called from threads
|
||||
def start_tiles(argList):
|
||||
blockID, start, stop, total = argList
|
||||
print("Running instance :" + str(blockID) + " / " + str(total))
|
||||
subprocess.check_call(
|
||||
"${XRAY_VIVADO} -mode batch -source $FUZDIR/jobtiles.tcl -tclargs " +
|
||||
str(blockID) + " " + str(start) + " " + str(stop),
|
||||
shell=True)
|
||||
|
||||
|
||||
def start_nodes(argList):
|
||||
blockID, start, stop, total = argList
|
||||
print("Running instance :" + str(blockID) + " / " + str(total))
|
||||
subprocess.check_call(
|
||||
"${XRAY_VIVADO} -mode batch -source $FUZDIR/jobnodes.tcl -tclargs " +
|
||||
str(blockID) + " " + str(start) + " " + str(stop),
|
||||
shell=True)
|
||||
|
||||
|
||||
# Function called once to get the total numbers of tiles to list
|
||||
def get_nb_tiles():
|
||||
print("Fetching total number of tiles")
|
||||
subprocess.check_call(
|
||||
"${XRAY_VIVADO} -mode batch -source $FUZDIR/get_tilescount.tcl",
|
||||
shell=True)
|
||||
countfile = open("nb_tiles.txt", "r")
|
||||
return int(countfile.readline())
|
||||
|
||||
|
||||
def get_nb_nodes():
|
||||
print("Fetching total number of nodes")
|
||||
subprocess.check_call(
|
||||
"${XRAY_VIVADO} -mode batch -source $FUZDIR/get_nodescount.tcl",
|
||||
shell=True)
|
||||
countfile = open("nb_nodes.txt", "r")
|
||||
return int(countfile.readline())
|
||||
|
||||
|
||||
def run_pool(itemcount, nbBlocks, blocksize, nbParBlock, workFunc):
|
||||
# We handle the case of not integer multiple of pips
|
||||
intitemcount = blocksize * nbBlocks
|
||||
lastRun = False
|
||||
modBlocks = itemcount % nbBlocks
|
||||
if modBlocks != 0:
|
||||
lastRun = True
|
||||
nbBlocks = nbBlocks + 1
|
||||
|
||||
print(
|
||||
"Items Count: " + str(itemcount) + " - Number of blocks: " +
|
||||
str(nbBlocks) + " - Parallel blocks: " + str(nbParBlock) +
|
||||
" - Blocksize: " + str(blocksize) + " - Modulo Blocks: " +
|
||||
str(modBlocks))
|
||||
|
||||
blockId = range(0, nbBlocks)
|
||||
startI = range(0, intitemcount, blocksize)
|
||||
stopI = range(blocksize, intitemcount + 1, blocksize)
|
||||
totalBlock = [nbBlocks for _ in range(nbBlocks)]
|
||||
|
||||
# In case we have a last incomplete block we add it as a last
|
||||
# element in the arguments list
|
||||
if lastRun == True:
|
||||
startI = chain(startI, [intitemcount])
|
||||
stopI = chain(stopI, [itemcount])
|
||||
|
||||
argList = zip(blockId, startI, stopI, totalBlock)
|
||||
|
||||
with Pool(processes=nbParBlock) as pool:
|
||||
pool.map(workFunc, argList)
|
||||
|
||||
return nbBlocks
|
||||
|
||||
|
||||
# ==========================================================================
|
||||
# ===== FPGA Logic Items data ==============================================
|
||||
# For Artix 7 50T:
|
||||
# - Total pips: 22002368
|
||||
# - Total tiles: 18055
|
||||
# - Total nodes: 1953452
|
||||
# For Kintex 7 70T:
|
||||
# - Total pips: 29424910
|
||||
# - Total tiles: 24453
|
||||
# - Total nodes: 2663055
|
||||
# For Zynq 7 z010:
|
||||
# - Total pips: 12462138
|
||||
# - Total tiles: 13440
|
||||
# - Total nodes: 1122477
|
||||
# =========================================================================
|
||||
# Dividing by about 64 over 4 core is not optimized but a default to run
|
||||
# on most computer
|
||||
# =========================================================================
|
||||
|
||||
|
||||
def main(argv):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--nbPar",
|
||||
help="Number of parallel instances of Vivado",
|
||||
type=int,
|
||||
default=4)
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--sizeTilesBlock",
|
||||
help="Define the number of tiles to process per instance",
|
||||
type=int,
|
||||
default=300)
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--sizeNodesBlock",
|
||||
help="Define the number of nodes to process per instance",
|
||||
type=int,
|
||||
default=30000)
|
||||
args = parser.parse_args()
|
||||
|
||||
nbParBlock = args.nbPar
|
||||
blockTilesSize = args.sizeTilesBlock
|
||||
blockNodesSize = args.sizeNodesBlock
|
||||
|
||||
print(
|
||||
" nbPar: " + str(nbParBlock) + " blockTilesSize: " +
|
||||
str(blockTilesSize) + " blockNodesSize: " + str(blockNodesSize))
|
||||
|
||||
tilescount = get_nb_tiles()
|
||||
nbTilesBlocks = int(tilescount / blockTilesSize)
|
||||
|
||||
tilesFileCount = run_pool(
|
||||
tilescount, nbTilesBlocks, blockTilesSize, nbParBlock, start_tiles)
|
||||
|
||||
nodescount = get_nb_nodes()
|
||||
nbNodesBlocks = int(nodescount / blockNodesSize)
|
||||
|
||||
nodeFilesCount = run_pool(
|
||||
nodescount, nbNodesBlocks, blockNodesSize, nbParBlock, start_nodes)
|
||||
|
||||
print("Generating final csv files")
|
||||
|
||||
with open("root.csv", "w") as wfd:
|
||||
wfd.write("filetype,subtype,filename\n")
|
||||
for j in range(0, tilesFileCount):
|
||||
ftiles = "root_" + str(j) + ".csv"
|
||||
with open(ftiles, "r") as fd:
|
||||
shutil.copyfileobj(fd, wfd)
|
||||
for j in range(0, nodeFilesCount):
|
||||
fnodes = "root_node_" + str(j) + ".csv"
|
||||
with open(fnodes, "r") as fd:
|
||||
shutil.copyfileobj(fd, wfd)
|
||||
|
||||
print("Work done !")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
||||
Loading…
Reference in New Issue