From 0c6afb061c1cac99354d7b997448ec3580e84d0c Mon Sep 17 00:00:00 2001
From: Yaman Umuroglu <maltanar@gmail.com>
Date: Thu, 20 Aug 2020 11:55:26 +0200
Subject: [PATCH] [Core] work on making remote exec/thr test on Alveo too

---
 src/finn/core/remote_exec.py     | 60 +++++++++++++++++++++-----------
 src/finn/core/throughput_test.py | 41 ++++++++++++++++------
 2 files changed, 69 insertions(+), 32 deletions(-)

diff --git a/src/finn/core/remote_exec.py b/src/finn/core/remote_exec.py
index 214358608..b15d59f10 100644
--- a/src/finn/core/remote_exec.py
+++ b/src/finn/core/remote_exec.py
@@ -28,7 +28,7 @@
 
 import os
 import subprocess
-
+import warnings
 import numpy as np
 
 
@@ -43,15 +43,35 @@ def remote_exec(model, execution_context):
     pynq_password = model.get_metadata_prop("pynq_password")
     pynq_target_dir = model.get_metadata_prop("pynq_target_dir")
     deployment_dir = model.get_metadata_prop("pynq_deploy_dir")
+    platform = model.get_metadata_prop("platform")
+    assert platform in ["alveo", "zynq", "zynq-iodma"]
+    bitfile = model.get_metadata_prop("bitfile")
+    bitfile = os.path.basename(bitfile)
+    if pynq_password == "":
+        if "zynq" in platform:
+            raise Exception("PYNQ board remote exec needs password for sudo")
+        else:
+            local_prefix = ""  # assume we are using an ssh key
+            warnings.warn("Empty password, make sure you've set up an ssh key")
+    else:
+        local_prefix = "sshpass -p %s " % pynq_password
+
+    if platform == "alveo":
+        # Alveo can run without sudo but needs correct environment
+        remote_prefix = "conda activate finn-pynq-alveo; "
+    elif "zynq" in platform:
+        # PYNQ Zynq boards need to execute with sudo
+        remote_prefix = "echo %s | sudo -S " % pynq_password
+
     inp = execution_context[model.graph.input[0].name]
     # make copy of array before saving it
     inp = inp.copy()
+    bsize = inp.shape[0]
     np.save(os.path.join(deployment_dir, "input.npy"), inp)
     # extracting last folder of absolute path (deployment_dir)
     deployment_folder = os.path.basename(os.path.normpath(deployment_dir))
     # copy input to PYNQ board
-    cmd = "sshpass -p {} scp -P{} -r {}/input.npy {}@{}:{}/{}".format(
-        pynq_password,
+    cmd = local_prefix + "scp -P{} -r {}/input.npy {}@{}:{}/{}".format(
         pynq_port,
         deployment_dir,
         pynq_username,
@@ -60,38 +80,36 @@ def remote_exec(model, execution_context):
         deployment_folder,
     )
     bash_command = ["/bin/bash", "-c", cmd]
-    process_compile = subprocess.Popen(bash_command, stdout=subprocess.PIPE)
-    process_compile.communicate()
-    # set platform attribute for correct remote execution
-    platform = model.get_metadata_prop("platform")
-    assert platform in ["alveo", "zynq", "zynq-iodma"]
+    process_scp_in = subprocess.Popen(bash_command, stdout=subprocess.PIPE)
+    process_scp_in.communicate()
+    # use platform attribute for correct remote execution
     cmd = (
-        "sshpass -p {} ssh {}@{} -p {} "
-        '"cd {}/{}; echo "{}" | '
-        'sudo -S python3.6 driver.py --exec_mode="execute" --batchsize=1" '
-        '--bitfile="resizer.bit" --inputfile="input.npy" --outputfile="output.npy" '
-        '--platform="{}" '
+        local_prefix + "ssh {}@{} -p {} "
+        '"cd {}/{}; '
+        + remote_prefix
+        + "python3.6 driver.py --exec_mode=execute --batchsize={} "
+        "--bitfile={} --inputfile=input.npy --outputfile=output.npy "
+        '--platform={} "'
     ).format(
-        pynq_password,
         pynq_username,
         pynq_ip,
         pynq_port,
         pynq_target_dir,
         deployment_folder,
-        pynq_password,
+        bsize,
+        bitfile,
         platform,
     )
     bash_command = ["/bin/bash", "-c", cmd]
-    process_compile = subprocess.Popen(bash_command, stdout=subprocess.PIPE)
-    process_compile.communicate()
+    process_exec_accel = subprocess.Popen(bash_command, stdout=subprocess.PIPE)
+    process_exec_accel.communicate()
     # remove stale output file from local dir, if any
     try:
         os.remove("{}/output.npy".format(deployment_dir))
     except FileNotFoundError:
         pass
     # copy generated output to local
-    cmd = "sshpass -p {} scp -P{} {}@{}:{}/{}/output.npy {}".format(
-        pynq_password,
+    cmd = local_prefix + "scp -P{} {}@{}:{}/{}/output.npy {}".format(
         pynq_port,
         pynq_username,
         pynq_ip,
@@ -100,7 +118,7 @@ def remote_exec(model, execution_context):
         deployment_dir,
     )
     bash_command = ["/bin/bash", "-c", cmd]
-    process_compile = subprocess.Popen(bash_command, stdout=subprocess.PIPE)
-    process_compile.communicate()
+    process_scp_out = subprocess.Popen(bash_command, stdout=subprocess.PIPE)
+    process_scp_out.communicate()
     outp = np.load("{}/output.npy".format(deployment_dir))
     execution_context[model.graph.output[0].name] = outp
diff --git a/src/finn/core/throughput_test.py b/src/finn/core/throughput_test.py
index fbfe775e5..4fc81142c 100644
--- a/src/finn/core/throughput_test.py
+++ b/src/finn/core/throughput_test.py
@@ -29,7 +29,7 @@
 import os
 import subprocess
 import numpy as np
-
+import warnings
 from finn.util.basic import gen_finn_dt_tensor
 from finn.core.rtlsim_exec import rtlsim_exec
 
@@ -48,24 +48,44 @@ def throughput_test(model, batchsize=1000):
     deployment_dir = model.get_metadata_prop("pynq_deploy_dir")
     # extracting last folder of absolute path (deployment_dir)
     deployment_folder = os.path.basename(os.path.normpath(deployment_dir))
+    platform = model.get_metadata_prop("platform")
+    assert platform in ["alveo", "zynq", "zynq-iodma"]
+    bitfile = model.get_metadata_prop("bitfile")
+    bitfile = os.path.basename(bitfile)
+    if pynq_password == "":
+        if "zynq" in platform:
+            raise Exception("PYNQ board remote exec needs password for sudo")
+        else:
+            local_prefix = ""  # assume we are using an ssh key
+            warnings.warn("Empty password, make sure you've set up an ssh key")
+    else:
+        local_prefix = "sshpass -p %s " % pynq_password
+
+    if platform == "alveo":
+        # Alveo can run without sudo but needs correct environment
+        remote_prefix = "conda activate finn-pynq-alveo; "
+    elif "zynq" in platform:
+        # PYNQ Zynq boards need to execute with sudo
+        remote_prefix = "echo %s | sudo -S " % pynq_password
 
     cmd = (
-        "sshpass -p {} ssh {}@{} -p {} "
-        '"cd {}/{}; echo "{}" | '
-        'sudo -S python3.6 driver.py --exec_mode="throughput_test" --batchsize=%d"'
-        % batchsize
+        local_prefix + "ssh {}@{} -p {} "
+        '"cd {}/{}; '
+        + remote_prefix
+        + 'python3.6 driver.py --exec_mode="throughput_test" --batchsize=%d '
+        '--bitfile={} --platform={} "' % batchsize
     ).format(
-        pynq_password,
         pynq_username,
         pynq_ip,
         pynq_port,
         pynq_target_dir,
         deployment_folder,
-        pynq_password,
+        bitfile,
+        platform,
     )
     bash_command = ["/bin/bash", "-c", cmd]
-    process_compile = subprocess.Popen(bash_command, stdout=subprocess.PIPE)
-    process_compile.communicate()
+    process_throughput_test = subprocess.Popen(bash_command, stdout=subprocess.PIPE)
+    process_throughput_test.communicate()
 
     # remove any pre-existing metrics file
     try:
@@ -73,8 +93,7 @@ def throughput_test(model, batchsize=1000):
     except FileNotFoundError:
         pass
 
-    cmd = "sshpass -p {} scp -P{} {}@{}:{}/{}/nw_metrics.txt {}".format(
-        pynq_password,
+    cmd = local_prefix + "scp -P{} {}@{}:{}/{}/nw_metrics.txt {}".format(
         pynq_port,
         pynq_username,
         pynq_ip,
-- 
GitLab