From 968c8155b6b632ded50c485e80c75b77059aeabf Mon Sep 17 00:00:00 2001 From: SDA USR <1391+sdausr@users.noreply.gitenterprise.xilinx.com> Date: Fri, 8 Apr 2022 09:50:23 +0800 Subject: [PATCH] Squashed 'hpc' changes from 1992a84..f7d1abc (#546) f7d1abc Merge pull request #122 from tuol/disable_2_case ae62691 disable 2 case due to U250 platform change 3af143e Merge pull request #118 from tuol/fix_cr_1122542 3e7f919 temporally disable L3/tests/mlp, due to U250 platform change 1728d13 update opts.cfg 98d3f3f Merge pull request #117 from yuanqian/next 8639708 remove email from Jenkinsfile:https://jira.xilinx.com/browse/CR-1124831 18a7458 Merge pull request #116 from changg/wa_u280_201920 86e28ef WA for xilinx_u280_xdma_201920_3 07abe54 Merge pull request #114 from liyuanz/replace_cflags 7cb157c replace cflags with clflags 0196ded Merge pull request #113 from changg/cov_fix fc100b4 cov fix b201f43 cov fix 14067e6 Merge pull request #110 from liyuanz/next bbe42e9 fix bug 257677d Merge pull request #109 from changg/pr_108 79db50c fix makefiles 984a71c update Makefile and utils daf9820 Merge pull request #106 from liyuanz/replace_blacklist 28fe2ed replace whiltelist/blacklist to allowlist/blocklist 981b5a2 Merge pull request #105 from changg/pr_104 2f45a63 add time for hw_build a21b8db add time 7256e35 add time 5f2c36a Merge pull request #102 from changg/add_extraflags acce305 fix utils.mk 74536af fix utils.mk 3c0647e Merge pull request #101 from liyuanz/next fc26744 increase mem 7a1b220 Merge pull request #99 from changg/fix_mks 055c521 fix typ 44ff7b9 fix utils.mk 4050d17 Merge pull request #98 from liyuanz/replace_targets b0157d6 update targes e41fc60 Merge pull request #96 from changg/metadata f6d1e26 draft metadata 0bbb982 change 2021.2_stable_latest to 2022.1_stable_latest Co-authored-by: sdausr --- hpc/Jenkinsfile | 2 +- hpc/L1/meta/api.json | 610 ++++++++++++++++++ .../hw/cgSolver/test_gemv/description.json | 16 +- .../hw/cgSolver/update_pk/description.json | 16 +- .../update_rk_jacobi/description.json | 16 +- .../data_h128_w128_t10_pe2/description.json | 16 +- .../data_h128_w128_t15_pe2/description.json | 16 +- .../data_h128_w128_t10_pe2/description.json | 16 +- .../data_h128_w128_t15_pe4/description.json | 16 +- .../data_h128_w128_t2_pe2/description.json | 16 +- .../rtm3d/forward_hbc/tests/description.json | 16 +- .../RTM_x36_y60_z40_t4_p2/description.json | 25 +- .../RTM_x50_y60_z80_t4_p2/description.json | 16 +- .../RTM_x50_y60_z80_t9_p2/description.json | 16 +- .../RTM_x28_y25_z20_t1_p2/description.json | 16 +- .../RTM_x28_y36_z20_t_p2/description.json | 12 +- .../cg_gemv_jacobi/description.json | 8 +- .../benchmarks/cg_gemv_jacobi/preSysLink.tcl | 1 + hpc/L2/benchmarks/cg_gemv_jacobi/utils.mk | 19 +- .../cg_spmv_jacobi/description.json | 6 +- .../benchmarks/cg_spmv_jacobi/preSysLink.tcl | 1 + hpc/L2/benchmarks/cg_spmv_jacobi/utils.mk | 19 +- hpc/L2/meta/api.json | 166 +++++ .../krnl_cgSolver_gemv/description.json | 6 +- .../krnl_cgSolver_gemv/preSysLink.tcl | 1 + .../krnl_cgSolver_gemv/tests/description.json | 8 +- .../krnl_cgSolver_gemv/tests/preSysLink.tcl | 1 + .../krnl_cgSolver_gemv/tests/utils.mk | 19 +- .../cgSolver/krnl_cgSolver_gemv/utils.mk | 15 +- .../description.json | 8 +- .../preSysLink.tcl | 1 + .../tests/description.json | 8 +- .../tests/preSysLink.tcl | 1 + .../tests/utils.mk | 19 +- .../krnl_cgSolver_gemv_jacobi_16ch/utils.mk | 15 +- .../description.json | 8 +- .../preSysLink.tcl | 1 + .../tests/description.json | 8 +- .../tests/preSysLink.tcl | 1 + .../tests/utils.mk | 19 +- .../krnl_cgSolver_gemv_jacobi_1ch/utils.mk | 15 +- .../description.json | 8 +- .../preSysLink.tcl | 1 + .../tests/description.json | 8 +- .../tests/preSysLink.tcl | 1 + .../tests/utils.mk | 19 +- .../krnl_cgSolver_gemv_jacobi_8ch/utils.mk | 15 +- .../description.json | 6 +- .../preSysLink.tcl | 1 + .../krnl_cgSolver_spmv_jacobi_16ch/utils.mk | 19 +- hpc/L2/tests/mlp/fcn_1CU/description.json | 6 +- hpc/L2/tests/mlp/fcn_1CU/preSysLink.tcl | 1 + hpc/L2/tests/mlp/fcn_1CU/utils.mk | 15 +- hpc/L2/tests/mlp/fcn_4CU/Makefile | 205 ------ hpc/L2/tests/mlp/fcn_4CU/conn_u250.cfg | 12 - hpc/L2/tests/mlp/fcn_4CU/description.json | 109 ---- hpc/L2/tests/mlp/fcn_4CU/opts.cfg | 11 - hpc/L2/tests/mlp/fcn_4CU/params.mk | 52 -- hpc/L2/tests/mlp/fcn_4CU/params_azure.mk | 52 -- hpc/L2/tests/mlp/fcn_4CU/utils.mk | 209 ------ hpc/L2/tests/rtm2d/rtm/description.json | 4 +- hpc/L2/tests/rtm2d/rtm/preSysLink.tcl | 1 + .../dataset_h128_w128_t10_s1/description.json | 11 +- .../dataset_h128_w128_t10_s1/preSysLink.tcl | 1 + .../tests/dataset_h128_w128_t10_s1/utils.mk | 37 +- hpc/L2/tests/rtm2d/rtm/utils.mk | 15 +- .../tests/rtm2d/rtmbackward/description.json | 4 +- hpc/L2/tests/rtm2d/rtmbackward/preSysLink.tcl | 1 + .../dataset_h128_w128_t10/description.json | 4 +- .../dataset_h128_w128_t10/preSysLink.tcl | 1 + .../tests/dataset_h128_w128_t10/utils.mk | 37 +- hpc/L2/tests/rtm2d/rtmbackward/utils.mk | 15 +- .../tests/rtm2d/rtmforward/description.json | 4 +- hpc/L2/tests/rtm2d/rtmforward/preSysLink.tcl | 1 + .../dataset_h128_w128_t10/description.json | 4 +- .../dataset_h128_w128_t10/preSysLink.tcl | 1 + .../tests/dataset_h128_w128_t10/utils.mk | 37 +- hpc/L2/tests/rtm2d/rtmforward/utils.mk | 15 +- .../rtmforward_Domain_HBC/description.json | 6 +- .../rtmforward_Domain_HBC/preSysLink.tcl | 1 + .../dataset_z70_y60_x80_t4/description.json | 4 +- .../dataset_z70_y60_x80_t4/preSysLink.tcl | 1 + .../tests/dataset_z70_y60_x80_t4/utils.mk | 37 +- .../rtm3d/rtmforward_Domain_HBC/utils.mk | 15 +- .../rtmforward_Domain_RBC/description.json | 6 +- .../rtmforward_Domain_RBC/preSysLink.tcl | 1 + .../dataset_z90_y60_x80_t4/description.json | 13 +- .../dataset_z90_y60_x80_t4/preSysLink.tcl | 1 + .../tests/dataset_z90_y60_x80_t4/utils.mk | 37 +- .../rtm3d/rtmforward_Domain_RBC/utils.mk | 15 +- hpc/L3/examples/mlp/Makefile | 1 + hpc/L3/examples/mlp/description.json | 6 +- hpc/L3/examples/mlp/preSysLink.tcl | 1 + hpc/L3/examples/mlp/utils.mk | 37 +- hpc/L3/meta/api.json | 423 ++++++++++++ hpc/L3/tests/mlp/Makefile | 200 ------ hpc/L3/tests/mlp/conn_u250.cfg | 13 - hpc/L3/tests/mlp/data_64/matW1_0.bin | Bin 42720 -> 0 bytes hpc/L3/tests/mlp/data_64/matW2_0.bin | Bin 2400 -> 0 bytes hpc/L3/tests/mlp/data_64/matW3_0.bin | Bin 240 -> 0 bytes hpc/L3/tests/mlp/data_64/mat_input_0_64.bin | Bin 91136 -> 0 bytes .../mat_sigmoid_output_input_0_model_0.bin | Bin 768 -> 0 bytes hpc/L3/tests/mlp/data_64/matb1_0.bin | 2 - hpc/L3/tests/mlp/data_64/matb2_0.bin | 2 - hpc/L3/tests/mlp/data_64/matb3_0.bin | 1 - hpc/L3/tests/mlp/description.json | 99 --- hpc/L3/tests/mlp/fcn_test.cpp | 410 ------------ hpc/L3/tests/mlp/opts.cfg | 8 - hpc/L3/tests/mlp/params.mk | 78 --- hpc/L3/tests/mlp/run_test.sh | 20 - hpc/L3/tests/mlp/utils.mk | 219 ------- hpc/L3/tests/rtm2d/Makefile | 1 + hpc/L3/tests/rtm2d/description.json | 5 +- hpc/L3/tests/rtm2d/preSysLink.tcl | 1 + hpc/L3/tests/rtm2d/utils.mk | 52 +- 115 files changed, 1829 insertions(+), 2045 deletions(-) create mode 100644 hpc/L1/meta/api.json create mode 100644 hpc/L2/benchmarks/cg_gemv_jacobi/preSysLink.tcl create mode 100644 hpc/L2/benchmarks/cg_spmv_jacobi/preSysLink.tcl create mode 100644 hpc/L2/meta/api.json create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/preSysLink.tcl create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/preSysLink.tcl create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/preSysLink.tcl create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/preSysLink.tcl create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/preSysLink.tcl create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/preSysLink.tcl create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/preSysLink.tcl create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/preSysLink.tcl create mode 100644 hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/preSysLink.tcl create mode 100644 hpc/L2/tests/mlp/fcn_1CU/preSysLink.tcl delete mode 100644 hpc/L2/tests/mlp/fcn_4CU/Makefile delete mode 100644 hpc/L2/tests/mlp/fcn_4CU/conn_u250.cfg delete mode 100644 hpc/L2/tests/mlp/fcn_4CU/description.json delete mode 100644 hpc/L2/tests/mlp/fcn_4CU/opts.cfg delete mode 100644 hpc/L2/tests/mlp/fcn_4CU/params.mk delete mode 100644 hpc/L2/tests/mlp/fcn_4CU/params_azure.mk delete mode 100644 hpc/L2/tests/mlp/fcn_4CU/utils.mk create mode 100644 hpc/L2/tests/rtm2d/rtm/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm2d/rtmbackward/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm2d/rtmforward/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/preSysLink.tcl create mode 100644 hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/preSysLink.tcl create mode 100644 hpc/L3/examples/mlp/preSysLink.tcl create mode 100644 hpc/L3/meta/api.json delete mode 100644 hpc/L3/tests/mlp/Makefile delete mode 100644 hpc/L3/tests/mlp/conn_u250.cfg delete mode 100644 hpc/L3/tests/mlp/data_64/matW1_0.bin delete mode 100644 hpc/L3/tests/mlp/data_64/matW2_0.bin delete mode 100644 hpc/L3/tests/mlp/data_64/matW3_0.bin delete mode 100644 hpc/L3/tests/mlp/data_64/mat_input_0_64.bin delete mode 100644 hpc/L3/tests/mlp/data_64/mat_sigmoid_output_input_0_model_0.bin delete mode 100644 hpc/L3/tests/mlp/data_64/matb1_0.bin delete mode 100644 hpc/L3/tests/mlp/data_64/matb2_0.bin delete mode 100644 hpc/L3/tests/mlp/data_64/matb3_0.bin delete mode 100644 hpc/L3/tests/mlp/description.json delete mode 100644 hpc/L3/tests/mlp/fcn_test.cpp delete mode 100644 hpc/L3/tests/mlp/opts.cfg delete mode 100644 hpc/L3/tests/mlp/params.mk delete mode 100755 hpc/L3/tests/mlp/run_test.sh delete mode 100644 hpc/L3/tests/mlp/utils.mk create mode 100644 hpc/L3/tests/rtm2d/preSysLink.tcl diff --git a/hpc/Jenkinsfile b/hpc/Jenkinsfile index 7765c8e881..4aab14310a 100644 --- a/hpc/Jenkinsfile +++ b/hpc/Jenkinsfile @@ -2,4 +2,4 @@ VitisLibPipeline (branch: 'next', libname: 'xf_hpc', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', upstream_dependencies: 'xf_blas,next,../blas;xf_sparse,next,../sparse', - email: 'liangm@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_stable_latest') + devtest: 'RunDeploy.sh', TOOLVERSION: '2022.1_stable_latest') diff --git a/hpc/L1/meta/api.json b/hpc/L1/meta/api.json new file mode 100644 index 0000000000..9854bec414 --- /dev/null +++ b/hpc/L1/meta/api.json @@ -0,0 +1,610 @@ +{ + "schema": "vitis_libraries_api_list_schema-1.0", + "api_list": [ + { + "api_name": "xf::hpc::rtm::memSelStream", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::rtm::memSelStream", + "display_name": "memSelStream", + "brief": "memSelStream reads data alternatively from two memory addresses to a stream", + "target_domain": "", + "header_file_name": [ + "dataMover.hpp" + ], + "search_paths": [ + "L1/include/hw/rtm" + ], + "instance": "function", + "parameters": [ + { + "name": "t_InterfaceType", + "type": "typename", + "description": "is the datatype in memory" + }, + { + "name": "t_DataType", + "type": "typename", + "description": "is the datatype in of the stream" + } + ], + "ports": [ + { + "name": "p_n", + "direction": "", + "type": "unsigned int" + }, + { + "name": "p_k", + "direction": "", + "type": "unsigned int" + }, + { + "name": "p_mem0", + "direction": "", + "type": "t_InterfaceType *" + }, + { + "name": "p_mem1", + "direction": "", + "type": "t_InterfaceType *" + }, + { + "name": "p_str", + "direction": "", + "type": "hls::stream< t_DataType > &" + } + ] + } + }, + { + "api_name": "xf::hpc::rtm::streamSelMem", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::rtm::streamSelMem", + "display_name": "streamSelMem", + "brief": "streamSelMem reads write alternatively to two memory addresses from a stream", + "target_domain": "", + "header_file_name": [ + "dataMover.hpp" + ], + "search_paths": [ + "L1/include/hw/rtm" + ], + "instance": "function", + "parameters": [ + { + "name": "t_InterfaceType", + "type": "typename", + "description": "is the datatype in memory" + }, + { + "name": "t_DataType", + "type": "typename", + "description": "is the datatype in of the stream" + } + ], + "ports": [ + { + "name": "p_n", + "direction": "", + "type": "unsigned int" + }, + { + "name": "p_k", + "direction": "", + "type": "unsigned int" + }, + { + "name": "p_mem0", + "direction": "", + "type": "t_InterfaceType *" + }, + { + "name": "p_mem1", + "direction": "", + "type": "t_InterfaceType *" + }, + { + "name": "p_str", + "direction": "", + "type": "hls::stream< t_DataType > &" + } + ] + } + }, + { + "api_name": "xf::hpc::cg::stamp_signal", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::stamp_signal", + "display_name": "stamp_signal", + "brief": "", + "target_domain": "", + "header_file_name": [ + "cgtimer.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::cgTimer", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::cgTimer", + "display_name": "cgTimer", + "brief": "", + "target_domain": "", + "header_file_name": [ + "cgtimer.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::square", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::square", + "display_name": "square", + "brief": "", + "target_domain": "", + "header_file_name": [ + "nrm2s.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "unsigned int" + }, + { + "name": "t_IndexType", + "type": "typename" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::nrm2s", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::nrm2s", + "display_name": "nrm2s", + "brief": "", + "target_domain": "", + "header_file_name": [ + "nrm2s.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_LogParEntries", + "type": "unsigned int" + }, + { + "name": "t_IndexType", + "type": "typename" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::update_gemv", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::update_gemv", + "display_name": "update_gemv", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_gemv.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + }, + { + "name": "t_VecParEntries", + "type": "int" + }, + { + "name": "t_NumPorts", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::proc_update_pk", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::proc_update_pk", + "display_name": "proc_update_pk", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_pk.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::update_pk", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::update_pk", + "display_name": "update_pk", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_pk.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + }, + { + "name": "t_TkWidth", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::proc_update_rk", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::proc_update_rk", + "display_name": "proc_update_rk", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_rk.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::update_rk", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::update_rk", + "display_name": "update_rk", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_rk.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + }, + { + "name": "t_TkWidth", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::proc_update_xk", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::proc_update_xk", + "display_name": "proc_update_xk", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_xk.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::update_xk", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::update_xk", + "display_name": "update_xk", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_xk.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + }, + { + "name": "t_TkWidth", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::proc_update_xr", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::proc_update_xr", + "display_name": "proc_update_xr", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_xr.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::cg::update_xr", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::update_xr", + "display_name": "update_xr", + "brief": "", + "target_domain": "", + "header_file_name": [ + "update_xr.hpp" + ], + "search_paths": [ + "L1/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "int" + }, + { + "name": "t_TkWidth", + "type": "int" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::mlp::FcnScalePRelu", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::FcnScalePRelu", + "display_name": "FcnScalePRelu", + "brief": "", + "target_domain": "", + "header_file_name": [ + "activations.hpp" + ], + "search_paths": [ + "L1/include/hw/mlp" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::mlp::relu", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::relu", + "display_name": "relu", + "brief": "relu (rectified linear unit) is a very common activation function in deep neural network", + "target_domain": "", + "header_file_name": [ + "activations.hpp" + ], + "search_paths": [ + "L1/include/hw/mlp" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + } + ], + "ports": [ + { + "name": "x", + "direction": "", + "type": "t_DataType" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::sigmoid", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::sigmoid", + "display_name": "sigmoid", + "brief": "sigmoid function is a very common activation function in MLP", + "target_domain": "", + "header_file_name": [ + "activations.hpp" + ], + "search_paths": [ + "L1/include/hw/mlp" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + } + ], + "ports": [ + { + "name": "x", + "direction": "", + "type": "t_DataType" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::tansig", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::tansig", + "display_name": "tansig", + "brief": "tansig function is used as an activation function in some MLPs", + "target_domain": "", + "header_file_name": [ + "activations.hpp" + ], + "search_paths": [ + "L1/include/hw/mlp" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + } + ], + "ports": [ + { + "name": "x", + "direction": "", + "type": "t_DataType" + } + ] + } + } + ], + "target_domain": "" +} \ No newline at end of file diff --git a/hpc/L1/tests/hw/cgSolver/test_gemv/description.json b/hpc/L1/tests/hw/cgSolver/test_gemv/description.json index 0821a6cae4..65a71ac407 100644 --- a/hpc/L1/tests/hw/cgSolver/test_gemv/description.json +++ b/hpc/L1/tests/hw/cgSolver/test_gemv/description.json @@ -3,10 +3,10 @@ "clock": "3.3333", "description": "Xilinx HPC CG Update Vector Values", "flow": "hls", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -39,10 +39,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -52,8 +52,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] } } \ No newline at end of file diff --git a/hpc/L1/tests/hw/cgSolver/update_pk/description.json b/hpc/L1/tests/hw/cgSolver/update_pk/description.json index f5014e9eb8..b6e9391241 100644 --- a/hpc/L1/tests/hw/cgSolver/update_pk/description.json +++ b/hpc/L1/tests/hw/cgSolver/update_pk/description.json @@ -3,10 +3,10 @@ "clock": "3.3333", "description": "Xilinx HPC CG Update Vector Values", "flow": "hls", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -39,10 +39,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -52,8 +52,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] } } \ No newline at end of file diff --git a/hpc/L1/tests/hw/cgSolver/update_rk_jacobi/description.json b/hpc/L1/tests/hw/cgSolver/update_rk_jacobi/description.json index 93e4b2c44a..95a9c9a83d 100644 --- a/hpc/L1/tests/hw/cgSolver/update_rk_jacobi/description.json +++ b/hpc/L1/tests/hw/cgSolver/update_rk_jacobi/description.json @@ -3,10 +3,10 @@ "clock": "3.3333", "description": "Xilinx HPC CG Update Vector Values", "flow": "hls", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -39,10 +39,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -52,8 +52,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] } } \ No newline at end of file diff --git a/hpc/L1/tests/hw/rtm2d/backward/tests/data_h128_w128_t10_pe2/description.json b/hpc/L1/tests/hw/rtm2d/backward/tests/data_h128_w128_t10_pe2/description.json index d437b55c3e..d83d66d713 100644 --- a/hpc/L1/tests/hw/rtm2d/backward/tests/data_h128_w128_t10_pe2/description.json +++ b/hpc/L1/tests/hw/rtm2d/backward/tests/data_h128_w128_t10_pe2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM backward.data_h128_w128_t10_pe2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,10 +35,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -48,8 +48,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm2d/backward/tests/data_h128_w128_t15_pe2/description.json b/hpc/L1/tests/hw/rtm2d/backward/tests/data_h128_w128_t15_pe2/description.json index aab60c5510..c6b38065af 100644 --- a/hpc/L1/tests/hw/rtm2d/backward/tests/data_h128_w128_t15_pe2/description.json +++ b/hpc/L1/tests/hw/rtm2d/backward/tests/data_h128_w128_t15_pe2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM backward.data_h128_w128_t15_pe2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,10 +35,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -48,8 +48,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm2d/forward/tests/data_h128_w128_t10_pe2/description.json b/hpc/L1/tests/hw/rtm2d/forward/tests/data_h128_w128_t10_pe2/description.json index 73ae320a99..794b3c1415 100644 --- a/hpc/L1/tests/hw/rtm2d/forward/tests/data_h128_w128_t10_pe2/description.json +++ b/hpc/L1/tests/hw/rtm2d/forward/tests/data_h128_w128_t10_pe2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM forward.data_h128_w128_t10_pe2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,10 +35,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -48,8 +48,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm2d/forward/tests/data_h128_w128_t15_pe4/description.json b/hpc/L1/tests/hw/rtm2d/forward/tests/data_h128_w128_t15_pe4/description.json index f7180f3590..5fbe8a2812 100644 --- a/hpc/L1/tests/hw/rtm2d/forward/tests/data_h128_w128_t15_pe4/description.json +++ b/hpc/L1/tests/hw/rtm2d/forward/tests/data_h128_w128_t15_pe4/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM forward.data_h128_w128_t15_pe4", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,10 +35,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -48,8 +48,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm2d/laplacian/tests/data_h128_w128_t2_pe2/description.json b/hpc/L1/tests/hw/rtm2d/laplacian/tests/data_h128_w128_t2_pe2/description.json index a3ed8ba6ce..39af7c4a06 100644 --- a/hpc/L1/tests/hw/rtm2d/laplacian/tests/data_h128_w128_t2_pe2/description.json +++ b/hpc/L1/tests/hw/rtm2d/laplacian/tests/data_h128_w128_t2_pe2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM laplacian.data_h128_w128_t2_pe2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,10 +35,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -48,8 +48,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm3d/forward_hbc/tests/description.json b/hpc/L1/tests/hw/rtm3d/forward_hbc/tests/description.json index 181c38d887..cd1ed24cdf 100644 --- a/hpc/L1/tests/hw/rtm3d/forward_hbc/tests/description.json +++ b/hpc/L1/tests/hw/rtm3d/forward_hbc/tests/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM forward", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,10 +35,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 40960, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 40960, + "vivado_impl": 40960, "hls_csynth": 10240 }, "max_time_min": 900 @@ -48,8 +48,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x36_y60_z40_t4_p2/description.json b/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x36_y60_z40_t4_p2/description.json index 7a074c0762..937a07f77b 100644 --- a/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x36_y60_z40_t4_p2/description.json +++ b/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x36_y60_z40_t4_p2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM forward.RTM_x36_y60_z40_t4_p2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,21 +35,28 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 40960, + "vivado_impl": 40960, "hls_csynth": 10240 }, - "max_time_min": 720 + "max_time_min": { + "vivado_syn": 720, + "hls_csim": 720, + "hls_cosim": 900, + "vivado_impl": 720, + "hls_csynth": 720 + + } } ], "targets": [ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x50_y60_z80_t4_p2/description.json b/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x50_y60_z80_t4_p2/description.json index b0f5df6149..896a112305 100644 --- a/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x50_y60_z80_t4_p2/description.json +++ b/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x50_y60_z80_t4_p2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM forward.RTM_x50_y60_z80_t4_p2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,10 +35,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 40960, + "vivado_impl": 40960, "hls_csynth": 10240 }, "max_time_min": 1200 @@ -48,8 +48,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x50_y60_z80_t9_p2/description.json b/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x50_y60_z80_t9_p2/description.json index 1199ba88ca..b6d98b5acd 100644 --- a/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x50_y60_z80_t9_p2/description.json +++ b/hpc/L1/tests/hw/rtm3d/forward_rbc/tests/RTM_x50_y60_z80_t9_p2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM forward.RTM_x50_y60_z80_t9_p2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -34,10 +34,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 40960, + "vivado_impl": 40960, "hls_csynth": 10240 }, "max_time_min": 720 @@ -46,8 +46,8 @@ "targets": [ "hls_csim", "hls_csynth", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm3d/laplacian/tests/RTM_x28_y25_z20_t1_p2/description.json b/hpc/L1/tests/hw/rtm3d/laplacian/tests/RTM_x28_y25_z20_t1_p2/description.json index bdf2b8e7ef..144fe8c7cf 100644 --- a/hpc/L1/tests/hw/rtm3d/laplacian/tests/RTM_x28_y25_z20_t1_p2/description.json +++ b/hpc/L1/tests/hw/rtm3d/laplacian/tests/RTM_x28_y25_z20_t1_p2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC RTM laplacian.RTM_x28_y25_z20_t1_p2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -35,10 +35,10 @@ "env": "", "index": 0, "max_memory_MB": { - "hls_vivado_syn": 16384, + "vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "vivado_impl": 16384, "hls_csynth": 10240 }, "max_time_min": 300 @@ -48,8 +48,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L1/tests/hw/rtm3d/propagate/tests/RTM_x28_y36_z20_t_p2/description.json b/hpc/L1/tests/hw/rtm3d/propagate/tests/RTM_x28_y36_z20_t_p2/description.json index aa47e5d3f4..70979becd8 100644 --- a/hpc/L1/tests/hw/rtm3d/propagate/tests/RTM_x28_y36_z20_t_p2/description.json +++ b/hpc/L1/tests/hw/rtm3d/propagate/tests/RTM_x28_y36_z20_t_p2/description.json @@ -3,10 +3,10 @@ "description": "", "flow": "hls", "name": "Xilinx HPC_RTM.propagate.RTM_x28_y36_z20_t_p2", - "part_blacklist": [], - "part_whitelist": [], - "platform_blacklist": [], - "platform_whitelist": [ + "part_blocklist": [], + "part_allowlist": [], + "platform_blocklist": [], + "platform_allowlist": [ "u280", "aws-vu9p-f1", "vck190" @@ -42,8 +42,8 @@ "hls_csim", "hls_csynth", "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" + "vivado_syn", + "vivado_impl" ] }, "top": { diff --git a/hpc/L2/benchmarks/cg_gemv_jacobi/description.json b/hpc/L2/benchmarks/cg_gemv_jacobi/description.json index f056dea300..a698ab10a8 100644 --- a/hpc/L2/benchmarks/cg_gemv_jacobi/description.json +++ b/hpc/L2/benchmarks/cg_gemv_jacobi/description.json @@ -4,18 +4,18 @@ "description": "Xilinx HPC Benchmark", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280", "u50" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u50": { "v++": { "compiler": { - "cflags": [ + "clflags": [ ] } }, @@ -30,7 +30,7 @@ "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ ] } }, diff --git a/hpc/L2/benchmarks/cg_gemv_jacobi/preSysLink.tcl b/hpc/L2/benchmarks/cg_gemv_jacobi/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/benchmarks/cg_gemv_jacobi/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/benchmarks/cg_gemv_jacobi/utils.mk b/hpc/L2/benchmarks/cg_gemv_jacobi/utils.mk index 6eb1d68ea8..1fc0b68f2d 100644 --- a/hpc/L2/benchmarks/cg_gemv_jacobi/utils.mk +++ b/hpc/L2/benchmarks/cg_gemv_jacobi/utils.mk @@ -29,6 +29,10 @@ VPP_LDFLAGS += --report estimate VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) VPP_LDFLAGS += --profile_kernel data:all:all:all @@ -74,15 +78,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/benchmarks/cg_spmv_jacobi/description.json b/hpc/L2/benchmarks/cg_spmv_jacobi/description.json index c7b645816e..0e4ae3428d 100644 --- a/hpc/L2/benchmarks/cg_spmv_jacobi/description.json +++ b/hpc/L2/benchmarks/cg_spmv_jacobi/description.json @@ -4,17 +4,17 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ ] } }, diff --git a/hpc/L2/benchmarks/cg_spmv_jacobi/preSysLink.tcl b/hpc/L2/benchmarks/cg_spmv_jacobi/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/benchmarks/cg_spmv_jacobi/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/benchmarks/cg_spmv_jacobi/utils.mk b/hpc/L2/benchmarks/cg_spmv_jacobi/utils.mk index 6eb1d68ea8..1fc0b68f2d 100644 --- a/hpc/L2/benchmarks/cg_spmv_jacobi/utils.mk +++ b/hpc/L2/benchmarks/cg_spmv_jacobi/utils.mk @@ -29,6 +29,10 @@ VPP_LDFLAGS += --report estimate VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) VPP_LDFLAGS += --profile_kernel data:all:all:all @@ -74,15 +78,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/meta/api.json b/hpc/L2/meta/api.json new file mode 100644 index 0000000000..56550388a8 --- /dev/null +++ b/hpc/L2/meta/api.json @@ -0,0 +1,166 @@ +{ + "schema": "vitis_libraries_api_list_schema-1.0", + "api_list": [ + { + "api_name": "xf::hpc::cg::control", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::cg::control", + "display_name": "control", + "brief": "", + "target_domain": "", + "header_file_name": [ + "control.hpp" + ], + "search_paths": [ + "L2/include/hw/cgSolver" + ], + "instance": "function", + "parameters": [ + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_ParEntries", + "type": "uint32_t" + }, + { + "name": "t_InstrBytes", + "type": "uint32_t" + }, + { + "name": "t_NumTasks", + "type": "uint32_t" + }, + { + "name": "t_TkWidth", + "type": "uint32_t" + } + ], + "ports": [] + } + }, + { + "api_name": "xf::hpc::rtm::forward", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::rtm::forward", + "display_name": "forward", + "brief": "forward function is composed by multiple forward streaming modules", + "target_domain": "", + "header_file_name": [ + "rtmforward.hpp" + ], + "search_paths": [ + "L2/include/hw/rtm3d" + ], + "instance": "function", + "parameters": [ + { + "name": "t_NumFSMs", + "type": "int" + }, + { + "name": "t_DataType", + "type": "typename" + }, + { + "name": "t_InType", + "type": "typename" + }, + { + "name": "t_UpbType", + "type": "typename" + }, + { + "name": "t_RTM", + "type": "typename" + }, + { + "name": "t_Domain", + "type": "typename" + } + ], + "ports": [ + { + "name": "p_sel", + "direction": "", + "type": "bool" + }, + { + "name": "p_domain", + "direction": "", + "type": "const t_Domain &" + }, + { + "name": "p_sm", + "direction": "", + "type": "t_RTM[t_NumFSMs]," + }, + { + "name": "p_t", + "direction": "", + "type": "const unsigned int" + }, + { + "name": "p_src", + "direction": "", + "type": "const t_DataType *" + }, + { + "name": "p_v2dt2", + "direction": "", + "type": "const t_InType *" + }, + { + "name": "p_pi0", + "direction": "", + "type": "t_InType *" + }, + { + "name": "p_pi1", + "direction": "", + "type": "t_InType *" + }, + { + "name": "p_po0", + "direction": "", + "type": "t_InType *" + }, + { + "name": "p_po1", + "direction": "", + "type": "t_InType *" + }, + { + "name": "p_ppi0", + "direction": "", + "type": "t_InType *" + }, + { + "name": "p_ppi1", + "direction": "", + "type": "t_InType *" + }, + { + "name": "p_ppo0", + "direction": "", + "type": "t_InType *" + }, + { + "name": "p_ppo1", + "direction": "", + "type": "t_InType *" + }, + { + "name": "p_upb", + "direction": "", + "type": "t_UpbType *p_up" + } + ] + } + } + ], + "target_domain": "" +} \ No newline at end of file diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/description.json index ec72a9d4fe..2cd2841c07 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/description.json @@ -4,17 +4,17 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/description.json index 1ec241a458..9c5730650b 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/description.json @@ -4,18 +4,18 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280", "u50" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u50": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } @@ -31,7 +31,7 @@ "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/utils.mk index 6eb1d68ea8..1fc0b68f2d 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/tests/utils.mk @@ -29,6 +29,10 @@ VPP_LDFLAGS += --report estimate VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) VPP_LDFLAGS += --profile_kernel data:all:all:all @@ -74,15 +78,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/utils.mk index 6eb1d68ea8..a644768e69 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +207,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/description.json index 4bcb9b0078..2d93542082 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/description.json @@ -4,18 +4,18 @@ "description": "Xilinx HPC CG Test, GEMV Jacobi 16-channel", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280", "u50" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u50": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } @@ -31,7 +31,7 @@ "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/description.json index 0a9edda958..324e73116b 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/description.json @@ -4,18 +4,18 @@ "description": "Xilinx HPC CG Test, GEMV Jacobi 16-channel", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280", "u50" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u50": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } @@ -31,7 +31,7 @@ "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/utils.mk index 6eb1d68ea8..1fc0b68f2d 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/tests/utils.mk @@ -29,6 +29,10 @@ VPP_LDFLAGS += --report estimate VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) VPP_LDFLAGS += --profile_kernel data:all:all:all @@ -74,15 +78,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/utils.mk index 6eb1d68ea8..a644768e69 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_16ch/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +207,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/description.json index 2026b15a13..b2bc9d8f17 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/description.json @@ -4,18 +4,18 @@ "description": "Xilinx HPC CG Test, GEMV, Jacobi, 1-channel", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280", "u50" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u50": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } @@ -30,7 +30,7 @@ "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/description.json index 83b9c110cb..66600284de 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/description.json @@ -4,18 +4,18 @@ "description": "Xilinx HPC CG Test, GEMV, Jacobi, 1-channel", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280", "u50" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u50": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } @@ -30,7 +30,7 @@ "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/utils.mk index 6eb1d68ea8..1fc0b68f2d 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/tests/utils.mk @@ -29,6 +29,10 @@ VPP_LDFLAGS += --report estimate VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) VPP_LDFLAGS += --profile_kernel data:all:all:all @@ -74,15 +78,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/utils.mk index 6eb1d68ea8..a644768e69 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_1ch/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +207,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/description.json index db8aaaef7c..af5a84de36 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/description.json @@ -4,18 +4,18 @@ "description": "Xilinx HPC CG Test, GEMV, Jacobi, 8-channel", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280", "u50" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u50": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } @@ -30,7 +30,7 @@ "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/description.json index b9c2a67030..667fa02ad3 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/description.json @@ -4,18 +4,18 @@ "description": "Xilinx HPC CG Test, GEMV, Jacobi, 8-channel", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280", "u50" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u50": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } @@ -30,7 +30,7 @@ "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/utils.mk index 6eb1d68ea8..1fc0b68f2d 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/tests/utils.mk @@ -29,6 +29,10 @@ VPP_LDFLAGS += --report estimate VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) VPP_LDFLAGS += --profile_kernel data:all:all:all @@ -74,15 +78,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/utils.mk index 6eb1d68ea8..a644768e69 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_gemv_jacobi_8ch/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +207,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/description.json b/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/description.json index 59192796ea..0416e005bf 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/description.json +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/description.json @@ -4,17 +4,17 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "" ] } diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/preSysLink.tcl b/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/utils.mk b/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/utils.mk index 6eb1d68ea8..1fc0b68f2d 100644 --- a/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/utils.mk +++ b/hpc/L2/tests/cgSolver/krnl_cgSolver_spmv_jacobi_16ch/utils.mk @@ -29,6 +29,10 @@ VPP_LDFLAGS += --report estimate VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) VPP_LDFLAGS += --profile_kernel data:all:all:all @@ -74,15 +78,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif @@ -207,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/mlp/fcn_1CU/description.json b/hpc/L2/tests/mlp/fcn_1CU/description.json index 7e78ab827e..7234dd488f 100644 --- a/hpc/L2/tests/mlp/fcn_1CU/description.json +++ b/hpc/L2/tests/mlp/fcn_1CU/description.json @@ -5,10 +5,10 @@ "flow": "vitis", "platform_type": "pcie", "gui": false, - "platform_whitelist": [ + "platform_allowlist": [ "u250" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { @@ -20,7 +20,7 @@ }, "v++": { "compiler": { - "cflags": [ + "clflags": [ "--config PROJECT/conn_u250.cfg" ] } diff --git a/hpc/L2/tests/mlp/fcn_1CU/preSysLink.tcl b/hpc/L2/tests/mlp/fcn_1CU/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/mlp/fcn_1CU/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/mlp/fcn_1CU/utils.mk b/hpc/L2/tests/mlp/fcn_1CU/utils.mk index 2e98106af4..a03f79eb43 100644 --- a/hpc/L2/tests/mlp/fcn_1CU/utils.mk +++ b/hpc/L2/tests/mlp/fcn_1CU/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version older. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) endif @@ -199,3 +199,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/mlp/fcn_4CU/Makefile b/hpc/L2/tests/mlp/fcn_4CU/Makefile deleted file mode 100644 index b74667034d..0000000000 --- a/hpc/L2/tests/mlp/fcn_4CU/Makefile +++ /dev/null @@ -1,205 +0,0 @@ -# -# Copyright 2019-2021 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# makefile-generator v1.0.4 -# - -# ####################################### Help Section ##################################### -.PHONY: help - -help:: - $(ECHO) "Makefile Usage:" - $(ECHO) " make all TARGET= DEVICE= HOST_ARCH=" - $(ECHO) " Command to generate the design for specified Target and Shell." - $(ECHO) "" - $(ECHO) " make clean " - $(ECHO) " Command to remove the generated non-hardware files." - $(ECHO) "" - $(ECHO) " make cleanall" - $(ECHO) " Command to remove all the generated files." - $(ECHO) "" - $(ECHO) " make run TARGET= DEVICE= HOST_ARCH=" - $(ECHO) " Command to run application in emulation or on board." - $(ECHO) "" - $(ECHO) " make build TARGET= DEVICE= HOST_ARCH=" - $(ECHO) " Command to build xclbin application." - $(ECHO) "" - $(ECHO) " make host HOST_ARCH=" - $(ECHO) " Command to build host application." - $(ECHO) "" - -# ##################### Setting up default value of TARGET ########################## -TARGET ?= sw_emu - -# ################### Setting up default value of DEVICE ############################## -DEVICE ?= xilinx_u250_gen3x16_xdma_3_1_202020_1 - -# ###################### Setting up default value of HOST_ARCH ####################### -HOST_ARCH ?= x86 - -# #################### Checking if DEVICE in blacklist ############################# - -# #################### Checking if DEVICE in whitelist ############################ -ifneq ($(findstring u250, $(DEVICE)), u250) -$(error [ERROR]: This project is not supported for $(DEVICE).) -endif - -# ######################## Setting up Project Variables ################################# -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L2/*}') -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XFLIB_DIR = $(XF_PROJ_ROOT) - -# ######################### Include environment variables in utils.mk #################### -include ./utils.mk -XDEVICE := $(call device2xsa, $(DEVICE)) -TEMP_DIR := _x_temp.$(TARGET).$(XDEVICE) -TEMP_REPORT_DIR := $(CUR_DIR)/reports/_x.$(TARGET).$(XDEVICE) -BUILD_DIR := build_dir.$(TARGET).$(XDEVICE) -BUILD_REPORT_DIR := $(CUR_DIR)/reports/_build.$(TARGET).$(XDEVICE) -EMCONFIG_DIR := $(BUILD_DIR) -XCLBIN_DIR := $(CUR_DIR)/$(BUILD_DIR) -export XCL_BINDIR = $(XCLBIN_DIR) - -# ######################### Setting up Host Variables ######################### -#Include Required Host Source Files -HOST_SRCS += $(XFLIB_DIR)/L2/src/sw/mlp/api_fcn_multiInstr.cpp -HOST_SRCS += $(XFLIB_DIR)/../blas/L2/src/xcl2/xcl2.cpp -CXXFLAGS += -I$(XFLIB_DIR)/L2/include/sw/mlp -CXXFLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw/xf_blas/helpers/utils -CXXFLAGS += -I$(XFLIB_DIR)/../blas/L2/include/xcl2 -CXXFLAGS += -I$(XFLIB_DIR)/../blas/L2/include/memKernel/sw -CXXFLAGS += -I$(XFLIB_DIR)/../blas/L2/include/memKernel - -ifeq ($(TARGET),sw_emu) -CXXFLAGS += -D SW_EMU_TEST -endif - -ifeq ($(TARGET),hw_emu) -CXXFLAGS += -D HW_EMU_TEST -endif - -# ######################### Host compiler global settings ############################ -CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++11 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE -CXXFLAGS += -fmessage-length=0 -O3 -CXXFLAGS += -I$(CUR_DIR)/src/ - -ifeq ($(HOST_ARCH), x86) -LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel -endif - -# ################### Setting package and image directory ####################### - -EXE_NAME := host.exe -EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) -HOST_ARGS := $(BUILD_DIR)/fcn.xclbin 32 32 32 32 32 32 32 1 0 1 0 A B C X - -# ##################### Kernel compiler global settings ########################## -VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps --optimize 2 -VPP_FLAGS += --hls.jobs 8 -VPP_LDFLAGS += --vivado.synth.jobs 8 --vivado.impl.jobs 8 -ifneq (,$(shell echo $(XPLATFORM) | awk '/u250/')) -VPP_FLAGS += --config $(CUR_DIR)/conn_u250.cfg -endif - -VPP_FLAGS += -I$(XFLIB_DIR)/L1/include/hw/mlp -VPP_FLAGS += -I$(XFLIB_DIR)/L2/include/hw/mlp -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw/xf_blas -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw/xf_blas/gemm -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw/xf_blas/helpers/utils -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L2/include -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L2/include/memKernel/ -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L2/include/memKernel/hw/xf_blas - -fcnKernel_VPP_FLAGS += --hls.clock 250000000:fcnKernel -VPP_LDFLAGS_fcn += --kernel_frequency 250 - - -# Kernel linker flags -VPP_LDFLAGS_fcn_temp := --config opts.cfg -VPP_LDFLAGS_fcn += $(VPP_LDFLAGS_fcn_temp) - -# ############################ Declaring Binary Containers ########################## - -BINARY_CONTAINERS += $(BUILD_DIR)/fcn.xclbin -BINARY_CONTAINER_fcn_OBJS += $(TEMP_DIR)/fcnKernel.xo - -# ######################### Setting Targets of Makefile ################################ - --include ./params.mk -.PHONY: all clean cleanall docs emconfig -all: check_vpp check_platform check_sysroot $(EXE_FILE) $(BINARY_CONTAINERS) emconfig - -.PHONY: host -host: check_xrt check_sysroot $(EXE_FILE) - -.PHONY: xclbin -xclbin: check_vpp check_sysroot $(BINARY_CONTAINERS) - -.PHONY: build -build: xclbin - -# ################ Setting Rules for Binary Containers (Building Kernels) ################ -$(TEMP_DIR)/fcnKernel.xo: $(XFLIB_DIR)/L2/src/hw/mlp/fcnKernel.cpp - $(ECHO) "Compiling Kernel: fcnKernel" - mkdir -p $(TEMP_DIR) - $(VPP) -c $(fcnKernel_VPP_FLAGS) $(VPP_FLAGS) -k fcnKernel -I'$( ${BUILD_DIR}/config_info.dat diff --git a/hpc/L2/tests/mlp/fcn_4CU/params_azure.mk b/hpc/L2/tests/mlp/fcn_4CU/params_azure.mk deleted file mode 100644 index e70652ea22..0000000000 --- a/hpc/L2/tests/mlp/fcn_4CU/params_azure.mk +++ /dev/null @@ -1,52 +0,0 @@ -BLAS_ddrWidth=16 -BLAS_XddrWidth=16 -BLAS_argInstrWidth=1 - -BLAS_dataType=float -BLAS_gemmMBlocks=1 -BLAS_gemmKBlocks=2 -BLAS_gemmNBlocks=1 - -BLAS_argPipeline = 2 -BLAS_instructionSizeBytes = 64 -BLAS_numKernels = 3 - -BLAS_dataEqIntType = float -BLAS_XdataType = float -BLAS_argInstrWidth = 1 -BLAS_numInstr = 64 -TEST_MEMCPY = 0 -BLAS_CACHE = 1 -BLAS_XVEC = 1 - -#MACROS += -D MLP_TANSIG=1 -#MACROS += -D MLP_RELU=1 - -MACROS += -D TEST_MEMCPY=$(TEST_MEMCPY) \ - -D BLAS_instructionSizeBytes=$(BLAS_instructionSizeBytes) \ - -D BLAS_dataType=$(BLAS_dataType) \ - -D BLAS_dataEqIntType=$(BLAS_dataEqIntType) \ - -D BLAS_ddrWidth=$(BLAS_ddrWidth) \ - -D BLAS_argInstrWidth=$(BLAS_argInstrWidth) \ - -D BLAS_numInstr=$(BLAS_numInstr) \ - -D BLAS_argPipeline=$(BLAS_argPipeline) \ - -D BLAS_runTransp=0 \ - -D BLAS_runGemv=0 \ - -D BLAS_runGemm=0 \ - -D BLAS_runFcn=1 \ - -D BLAS_numKernels=${BLAS_numKernels}\ - -D BLAS_CACHE=${BLAS_CACHE}\ - -D BLAS_XVEC=${BLAS_XVEC} \ - -D BLAS_gemmMBlocks=${BLAS_gemmMBlocks} \ - -D BLAS_gemmKBlocks=${BLAS_gemmKBlocks} \ - -D BLAS_gemmNBlocks=${BLAS_gemmNBlocks} \ - -D BLAS_XdataType=$(BLAS_XdataType) \ - -D BLAS_XddrWidth=$(BLAS_XddrWidth) \ - -CXXFLAGS += ${MACROS} -VPP_FLAGS += ${MACROS} - -CONFIG_INFO = $(shell echo ${MACROS} | sed 's/-D //g; s/ -Wno.*//') - -dump_config: - @echo ${CONFIG_INFO} | tr " " "\n" > ${BUILD_DIR}/config_info.dat diff --git a/hpc/L2/tests/mlp/fcn_4CU/utils.mk b/hpc/L2/tests/mlp/fcn_4CU/utils.mk deleted file mode 100644 index 6eb1d68ea8..0000000000 --- a/hpc/L2/tests/mlp/fcn_4CU/utils.mk +++ /dev/null @@ -1,209 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -#+------------------------------------------------------------------------------- -# The following parameters are assigned with default values. These parameters can -# be overridden through the make command line -#+------------------------------------------------------------------------------- - -REPORT := no -PROFILE := no -DEBUG := no - -#'estimate' for estimate report generation -#'system' for system report generation -ifneq ($(REPORT), no) -VPP_LDFLAGS += --report estimate -VPP_LDFLAGS += --report system -endif - -#Generates profile summary report -ifeq ($(PROFILE), yes) -VPP_LDFLAGS += --profile_kernel data:all:all:all -endif - -#Generates debug summary report -ifeq ($(DEBUG), yes) -VPP_LDFLAGS += --dk protocol:all:all:all -endif - -#Check environment setup -ifndef XILINX_VITIS - XILINX_VITIS = /opt/xilinx/Vitis/$(TOOL_VERSION) - export XILINX_VITIS -endif -ifndef XILINX_XRT - XILINX_XRT = /opt/xilinx/xrt - export XILINX_XRT -endif - -#Checks for Device Family -ifeq ($(HOST_ARCH), aarch32) - DEV_FAM = 7Series -else ifeq ($(HOST_ARCH), aarch64) - DEV_FAM = Ultrascale -endif - -B_NAME = $(shell dirname $(XPLATFORM)) - -#Checks for Correct architecture -ifneq ($(HOST_ARCH), $(filter $(HOST_ARCH),aarch64 aarch32 x86)) -$(error HOST_ARCH variable not set, please set correctly and rerun) -endif - -#Checks for SYSROOT -check_sysroot: -ifneq ($(HOST_ARCH), x86) -ifndef SYSROOT - $(error SYSROOT ENV variable is not set, please set ENV variable correctly and rerun) -endif -endif - -#Checks for g++ -CXX := g++ -ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) -ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) -else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ -ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 -else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) -endif -$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) -endif -endif -else ifeq ($(HOST_ARCH), aarch64) -CXX := $(XILINX_VITIS)/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-g++ -else ifeq ($(HOST_ARCH), aarch32) -CXX := $(XILINX_VITIS)/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++ -endif - -#Setting VPP -VPP := v++ - -#Cheks for aiecompiler - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) -ifeq ($(HOST_ARCH), x86) -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -else # aarch64 -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(SYSROOT)/usr/lib -else -LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) -endif -endif - -# check target -ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) -$(error TARGET is not sw_emu, hw_emu or hw) -endif - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE)/$(DEVICE).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE)/$(DEVICE).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE)/$(DEVICE).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif -#Check ends - -# device2xsa - create a filesystem friendly name from device name -# $(1) - full name of device -device2xsa = $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) - -# Cleaning stuff -RM = rm -f -RMDIR = rm -rf - -MV = mv -f -CP = cp -rf -ECHO:= @echo diff --git a/hpc/L2/tests/rtm2d/rtm/description.json b/hpc/L2/tests/rtm2d/rtm/description.json index 25bdd759af..d5421c294f 100644 --- a/hpc/L2/tests/rtm2d/rtm/description.json +++ b/hpc/L2/tests/rtm2d/rtm/description.json @@ -4,10 +4,10 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { diff --git a/hpc/L2/tests/rtm2d/rtm/preSysLink.tcl b/hpc/L2/tests/rtm2d/rtm/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm2d/rtm/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/description.json b/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/description.json index 0a12544363..7e1cca05d6 100644 --- a/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/description.json +++ b/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/description.json @@ -4,10 +4,10 @@ "description": "Xilinx RTM Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { @@ -111,7 +111,12 @@ "vitis_sw_emu": 10240, "vitis_hw_run": 10240 }, - "max_time_min": 520 + "max_time_min": { + "vitis_hw_build": 900, + "vitis_hw_emu": 520, + "vitis_sw_emu": 520, + "vitis_hw_run": 520 + } } ], "targets": [ diff --git a/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/preSysLink.tcl b/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/utils.mk b/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/utils.mk index 2e98106af4..1fc0b68f2d 100644 --- a/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/utils.mk +++ b/hpc/L2/tests/rtm2d/rtm/tests/dataset_h128_w128_t10_s1/utils.mk @@ -25,18 +25,22 @@ DEBUG := no #'estimate' for estimate report generation #'system' for system report generation ifneq ($(REPORT), no) -LDCLFLAGS += --report estimate -LDCLFLAGS += --report system +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) -LDCLFLAGS += --profile_kernel data:all:all:all +VPP_LDFLAGS += --profile_kernel data:all:all:all endif #Generates debug summary report ifeq ($(DEBUG), yes) -LDCLFLAGS += --dk protocol:all:all:all +VPP_LDFLAGS += --dk protocol:all:all:all endif #Check environment setup @@ -74,17 +78,17 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif -$(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif endif else ifeq ($(HOST_ARCH), aarch64) @@ -117,11 +121,19 @@ ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) endif export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) ifeq (,$(LD_LIBRARY_PATH)) LD_LIBRARY_PATH := $(XILINX_XRT)/lib else LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) endif +else # aarch64 +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib +else +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) +endif +endif # check target ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) @@ -199,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm2d/rtm/utils.mk b/hpc/L2/tests/rtm2d/rtm/utils.mk index 2e98106af4..a03f79eb43 100644 --- a/hpc/L2/tests/rtm2d/rtm/utils.mk +++ b/hpc/L2/tests/rtm2d/rtm/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version older. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) endif @@ -199,3 +199,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm2d/rtmbackward/description.json b/hpc/L2/tests/rtm2d/rtmbackward/description.json index 00b1d75fac..ddab088530 100644 --- a/hpc/L2/tests/rtm2d/rtmbackward/description.json +++ b/hpc/L2/tests/rtm2d/rtmbackward/description.json @@ -4,10 +4,10 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { diff --git a/hpc/L2/tests/rtm2d/rtmbackward/preSysLink.tcl b/hpc/L2/tests/rtm2d/rtmbackward/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm2d/rtmbackward/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/description.json b/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/description.json index ae045c8847..9e4014d2b0 100644 --- a/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/description.json +++ b/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/description.json @@ -4,10 +4,10 @@ "description": "Xilinx RTM Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { diff --git a/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/preSysLink.tcl b/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/utils.mk b/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/utils.mk index 2e98106af4..1fc0b68f2d 100644 --- a/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/utils.mk +++ b/hpc/L2/tests/rtm2d/rtmbackward/tests/dataset_h128_w128_t10/utils.mk @@ -25,18 +25,22 @@ DEBUG := no #'estimate' for estimate report generation #'system' for system report generation ifneq ($(REPORT), no) -LDCLFLAGS += --report estimate -LDCLFLAGS += --report system +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) -LDCLFLAGS += --profile_kernel data:all:all:all +VPP_LDFLAGS += --profile_kernel data:all:all:all endif #Generates debug summary report ifeq ($(DEBUG), yes) -LDCLFLAGS += --dk protocol:all:all:all +VPP_LDFLAGS += --dk protocol:all:all:all endif #Check environment setup @@ -74,17 +78,17 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif -$(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif endif else ifeq ($(HOST_ARCH), aarch64) @@ -117,11 +121,19 @@ ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) endif export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) ifeq (,$(LD_LIBRARY_PATH)) LD_LIBRARY_PATH := $(XILINX_XRT)/lib else LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) endif +else # aarch64 +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib +else +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) +endif +endif # check target ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) @@ -199,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm2d/rtmbackward/utils.mk b/hpc/L2/tests/rtm2d/rtmbackward/utils.mk index 2e98106af4..a03f79eb43 100644 --- a/hpc/L2/tests/rtm2d/rtmbackward/utils.mk +++ b/hpc/L2/tests/rtm2d/rtmbackward/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version older. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) endif @@ -199,3 +199,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm2d/rtmforward/description.json b/hpc/L2/tests/rtm2d/rtmforward/description.json index 80b61c93fe..b837e1f091 100644 --- a/hpc/L2/tests/rtm2d/rtmforward/description.json +++ b/hpc/L2/tests/rtm2d/rtmforward/description.json @@ -4,10 +4,10 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { diff --git a/hpc/L2/tests/rtm2d/rtmforward/preSysLink.tcl b/hpc/L2/tests/rtm2d/rtmforward/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm2d/rtmforward/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/description.json b/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/description.json index d9314a2167..787b4ee30e 100644 --- a/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/description.json +++ b/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/description.json @@ -4,10 +4,10 @@ "description": "Xilinx RTM Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { diff --git a/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/preSysLink.tcl b/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/utils.mk b/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/utils.mk index 2e98106af4..1fc0b68f2d 100644 --- a/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/utils.mk +++ b/hpc/L2/tests/rtm2d/rtmforward/tests/dataset_h128_w128_t10/utils.mk @@ -25,18 +25,22 @@ DEBUG := no #'estimate' for estimate report generation #'system' for system report generation ifneq ($(REPORT), no) -LDCLFLAGS += --report estimate -LDCLFLAGS += --report system +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) -LDCLFLAGS += --profile_kernel data:all:all:all +VPP_LDFLAGS += --profile_kernel data:all:all:all endif #Generates debug summary report ifeq ($(DEBUG), yes) -LDCLFLAGS += --dk protocol:all:all:all +VPP_LDFLAGS += --dk protocol:all:all:all endif #Check environment setup @@ -74,17 +78,17 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif -$(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif endif else ifeq ($(HOST_ARCH), aarch64) @@ -117,11 +121,19 @@ ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) endif export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) ifeq (,$(LD_LIBRARY_PATH)) LD_LIBRARY_PATH := $(XILINX_XRT)/lib else LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) endif +else # aarch64 +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib +else +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) +endif +endif # check target ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) @@ -199,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm2d/rtmforward/utils.mk b/hpc/L2/tests/rtm2d/rtmforward/utils.mk index 2e98106af4..a03f79eb43 100644 --- a/hpc/L2/tests/rtm2d/rtmforward/utils.mk +++ b/hpc/L2/tests/rtm2d/rtmforward/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version older. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) endif @@ -199,3 +199,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/description.json b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/description.json index e2b5a710f9..bc508a18e9 100644 --- a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/description.json +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/description.json @@ -4,17 +4,17 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "--config PROJECT/conn_u280.cfg" ] } diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/preSysLink.tcl b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/description.json b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/description.json index 4725623212..e6fc2741d2 100644 --- a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/description.json +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/description.json @@ -4,10 +4,10 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/preSysLink.tcl b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/utils.mk b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/utils.mk index 2e98106af4..1fc0b68f2d 100644 --- a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/utils.mk +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/tests/dataset_z70_y60_x80_t4/utils.mk @@ -25,18 +25,22 @@ DEBUG := no #'estimate' for estimate report generation #'system' for system report generation ifneq ($(REPORT), no) -LDCLFLAGS += --report estimate -LDCLFLAGS += --report system +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) -LDCLFLAGS += --profile_kernel data:all:all:all +VPP_LDFLAGS += --profile_kernel data:all:all:all endif #Generates debug summary report ifeq ($(DEBUG), yes) -LDCLFLAGS += --dk protocol:all:all:all +VPP_LDFLAGS += --dk protocol:all:all:all endif #Check environment setup @@ -74,17 +78,17 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif -$(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif endif else ifeq ($(HOST_ARCH), aarch64) @@ -117,11 +121,19 @@ ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) endif export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) ifeq (,$(LD_LIBRARY_PATH)) LD_LIBRARY_PATH := $(XILINX_XRT)/lib else LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) endif +else # aarch64 +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib +else +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) +endif +endif # check target ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) @@ -199,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/utils.mk b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/utils.mk index 2e98106af4..a03f79eb43 100644 --- a/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/utils.mk +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_HBC/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version older. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) endif @@ -199,3 +199,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/description.json b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/description.json index eab9fb9e5e..14b06bf9d3 100644 --- a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/description.json +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/description.json @@ -4,17 +4,17 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "--config PROJECT/conn_u280.cfg" ] } diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/preSysLink.tcl b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/description.json b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/description.json index ee6c70d794..dfa7e40d44 100644 --- a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/description.json +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/description.json @@ -4,17 +4,17 @@ "description": "Xilinx HPC Test", "flow": "vitis", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { "u280": { "v++": { "compiler": { - "cflags": [ + "clflags": [ "--config PROJECT/conn_u280.cfg" ] } @@ -108,7 +108,12 @@ "vitis_sw_emu": 10240, "vitis_hw_run": 10240 }, - "max_time_min": 640 + "max_time_min": { + "vitis_hw_build": 1200, + "vitis_hw_emu": 1200, + "vitis_sw_emu": 640, + "vitis_hw_run": 640 + } } ], "targets": [ diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/preSysLink.tcl b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/utils.mk b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/utils.mk index 2e98106af4..1fc0b68f2d 100644 --- a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/utils.mk +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/tests/dataset_z90_y60_x80_t4/utils.mk @@ -25,18 +25,22 @@ DEBUG := no #'estimate' for estimate report generation #'system' for system report generation ifneq ($(REPORT), no) -LDCLFLAGS += --report estimate -LDCLFLAGS += --report system +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) -LDCLFLAGS += --profile_kernel data:all:all:all +VPP_LDFLAGS += --profile_kernel data:all:all:all endif #Generates debug summary report ifeq ($(DEBUG), yes) -LDCLFLAGS += --dk protocol:all:all:all +VPP_LDFLAGS += --dk protocol:all:all:all endif #Check environment setup @@ -74,17 +78,17 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif -$(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif endif else ifeq ($(HOST_ARCH), aarch64) @@ -117,11 +121,19 @@ ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) endif export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) ifeq (,$(LD_LIBRARY_PATH)) LD_LIBRARY_PATH := $(XILINX_XRT)/lib else LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) endif +else # aarch64 +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib +else +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) +endif +endif # check target ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) @@ -199,3 +211,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/utils.mk b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/utils.mk index 2e98106af4..a03f79eb43 100644 --- a/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/utils.mk +++ b/hpc/L2/tests/rtm3d/rtmforward_Domain_RBC/utils.mk @@ -74,15 +74,15 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version older. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif $(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) endif @@ -199,3 +199,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L3/examples/mlp/Makefile b/hpc/L3/examples/mlp/Makefile index fc2192b041..53a29a0d70 100644 --- a/hpc/L3/examples/mlp/Makefile +++ b/hpc/L3/examples/mlp/Makefile @@ -100,6 +100,7 @@ CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++14 -O3 -Wall LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE CXXFLAGS += -fmessage-length=0 CXXFLAGS += -I$(CUR_DIR)/src/ +CXXFLAGS += $(XRT_CXXFLAGS) ifeq ($(HOST_ARCH), x86) LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel diff --git a/hpc/L3/examples/mlp/description.json b/hpc/L3/examples/mlp/description.json index e5b348f3b1..4368f8921f 100644 --- a/hpc/L3/examples/mlp/description.json +++ b/hpc/L3/examples/mlp/description.json @@ -2,10 +2,10 @@ "name": "Xilinx XF_HPC FCN example", "description": "", "flow": "vitis", - "platform_whitelist": [ + "platform_allowlist": [ "u250" ], - "platform_blacklist": [], + "platform_blocklist": [], "platform_type" : "pcie", "gui": false, "platform_properties": { @@ -17,7 +17,7 @@ }, "v++": { "compiler": { - "cflags": [ + "clflags": [ "--config PROJECT/conn_u250.cfg" ] } diff --git a/hpc/L3/examples/mlp/preSysLink.tcl b/hpc/L3/examples/mlp/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L3/examples/mlp/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L3/examples/mlp/utils.mk b/hpc/L3/examples/mlp/utils.mk index 20fe55b5fb..015249a861 100644 --- a/hpc/L3/examples/mlp/utils.mk +++ b/hpc/L3/examples/mlp/utils.mk @@ -72,19 +72,25 @@ endif endif #Checks for g++ +VITIS_VER = $(shell v++ --version | grep 'v++' | sed 's/^[[:space:]]*//' | sed -e 's/^[*]* v++ v//g' | cut -d " " -f1) CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifeq ($(shell expr $(VITIS_VER) \>= 2022.1), 1) +CXX_VER := 8.3.0 +else +CXX_VER := 6.2.0 +endif +ifneq ($(shell expr $(shell echo "__GNUG__" | g++ -E -x c++ - | tail -1) \>= $(CXX_VER)), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use $(CXX_VER) or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-$(CXX_VER)/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-$(CXX_VER)/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-$(CXX_VER)/lib64:$(LD_LIBRARY_PATH) endif -$(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif endif else ifeq ($(HOST_ARCH), aarch64) @@ -93,13 +99,21 @@ else ifeq ($(HOST_ARCH), aarch32) CXX := $(XILINX_VITIS)/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++ endif -#Check OS and setting env +# for centos and redhat OSDIST = $(shell lsb_release -i |awk -F: '{print tolower($$2)}' | tr -d ' \t' ) OSREL = $(shell lsb_release -r |awk -F: '{print tolower($$2)}' |tr -d ' \t') -ifeq ($(OSDIST), centos) +ifneq ($(findstring centos,$(OSDIST)),) +ifeq (7,$(shell echo $(OSREL) | awk -F. '{print tolower($$1)}' )) +ifeq ($(HOST_ARCH), x86) +XRT_CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 +endif +endif +else ifneq ($(findstring redhat,$(OSDIST)),) ifeq (7,$(shell echo $(OSREL) | awk -F. '{print tolower($$1)}' )) -CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 +ifeq ($(HOST_ARCH), x86) +XRT_CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 +endif endif endif @@ -209,3 +223,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif diff --git a/hpc/L3/meta/api.json b/hpc/L3/meta/api.json new file mode 100644 index 0000000000..fa7d4ccc5d --- /dev/null +++ b/hpc/L3/meta/api.json @@ -0,0 +1,423 @@ +{ + "schema": "vitis_libraries_api_list_schema-1.0", + "api_list": [ + { + "api_name": "xf::hpc::mlp::xfhpcCreate", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcCreate", + "display_name": "xfhpcCreate", + "brief": "This function initializes the XFHPC library and creates a handle for the specific engine. It must be called prior to any other XFHPC library calls.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "xclbin", + "direction": "", + "type": "const char *" + }, + { + "name": "kernelNumber", + "direction": "", + "type": "unsigned int=1," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcMalloc", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcMalloc", + "display_name": "xfhpcMalloc", + "brief": "This function allocates memory for host row-major format matrix on the FPGA device.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "rows", + "direction": "", + "type": "int" + }, + { + "name": "cols", + "direction": "", + "type": "int" + }, + { + "name": "elemSize", + "direction": "", + "type": "int" + }, + { + "name": "A", + "direction": "", + "type": "void *" + }, + { + "name": "lda", + "direction": "", + "type": "int" + }, + { + "name": "kernelIndex", + "direction": "", + "type": "unsigned int=0," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcSetMatrix", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcSetMatrix", + "display_name": "xfhpcSetMatrix", + "brief": "This function copies a matrix in host memory to FPGA device memory. xfhpcMallocRestricted() need to be called prior to this function.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "A", + "direction": "", + "type": "void *" + }, + { + "name": "kernelIndex", + "direction": "", + "type": "unsigned int=0," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcGetMatrix", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcGetMatrix", + "display_name": "xfhpcGetMatrix", + "brief": "This function copies a matrix in FPGA device memory to host memory.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "A", + "direction": "", + "type": "void *" + }, + { + "name": "kernelIndex", + "direction": "", + "type": "unsigned int=0," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcFree", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcFree", + "display_name": "xfhpcFree", + "brief": "This function frees memory in FPGA device.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "A", + "direction": "", + "type": "void *" + }, + { + "name": "kernelIndex", + "direction": "", + "type": "unsigned int=0," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcFreeInstr", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcFreeInstr", + "display_name": "xfhpcFreeInstr", + "brief": "This function frees instrution.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "kernelIndex", + "direction": "", + "type": "unsigned int=0," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcDestroy", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcDestroy", + "display_name": "xfhpcDestroy", + "brief": "This function releases handle used by the XFHPC library.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "kernelNumber", + "direction": "", + "type": "unsigned int=1," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcFcn", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcFcn", + "display_name": "xfhpcFcn", + "brief": "", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcExecute", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcExecute", + "display_name": "xfhpcExecute", + "brief": "This function starts the kernel and wait until it finishes.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "kernelIndex", + "direction": "", + "type": "unsigned int=0," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcExecuteAsync", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcExecuteAsync", + "display_name": "xfhpcExecuteAsync", + "brief": "This asynchronous function starts all kernels and wait until them finish.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "numKernels", + "direction": "", + "type": "unsigned int=1," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcGetByAddress", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcGetByAddress", + "display_name": "xfhpcGetByAddress", + "brief": "This function copies a matrix in FPGA device memory to host memory by its address in device memory.", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [ + { + "name": "A", + "direction": "", + "type": "void *" + }, + { + "name": "p_bufSize", + "direction": "", + "type": "unsigned long long" + }, + { + "name": "offset", + "direction": "", + "type": "unsigned int" + }, + { + "name": "kernelIndex", + "direction": "", + "type": "unsigned int=0," + }, + { + "name": "deviceIndex", + "direction": "", + "type": "unsigned int" + } + ] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcGetByPointer", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcGetByPointer", + "display_name": "xfhpcGetByPointer", + "brief": "", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [] + } + }, + { + "api_name": "xf::hpc::mlp::xfhpcFcnByAddress", + "spec": { + "schema": "vitis_libraries_api_list_schema-1.0", + "api_name": "xf::hpc::mlp::xfhpcFcnByAddress", + "display_name": "xfhpcFcnByAddress", + "brief": "", + "target_domain": "", + "header_file_name": [ + "mlp_wrapper.hpp" + ], + "search_paths": [ + "L3/include/sw/mlp" + ], + "instance": "function", + "parameters": [], + "ports": [] + } + } + ], + "target_domain": "" +} \ No newline at end of file diff --git a/hpc/L3/tests/mlp/Makefile b/hpc/L3/tests/mlp/Makefile deleted file mode 100644 index bde471fc14..0000000000 --- a/hpc/L3/tests/mlp/Makefile +++ /dev/null @@ -1,200 +0,0 @@ -# -# Copyright 2019-2021 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# makefile-generator v1.0.4 -# - -# ####################################### Help Section ##################################### -.PHONY: help - -help:: - $(ECHO) "Makefile Usage:" - $(ECHO) " make all TARGET= DEVICE= HOST_ARCH=" - $(ECHO) " Command to generate the design for specified Target and Shell." - $(ECHO) "" - $(ECHO) " make clean " - $(ECHO) " Command to remove the generated non-hardware files." - $(ECHO) "" - $(ECHO) " make cleanall" - $(ECHO) " Command to remove all the generated files." - $(ECHO) "" - $(ECHO) " make run TARGET= DEVICE= HOST_ARCH=" - $(ECHO) " Command to run application in emulation or on board." - $(ECHO) "" - $(ECHO) " make build TARGET= DEVICE= HOST_ARCH=" - $(ECHO) " Command to build xclbin application." - $(ECHO) "" - $(ECHO) " make host HOST_ARCH=" - $(ECHO) " Command to build host application." - $(ECHO) "" - -# ##################### Setting up default value of TARGET ########################## -TARGET ?= sw_emu - -# ################### Setting up default value of DEVICE ############################## -DEVICE ?= xilinx_u250_gen3x16_xdma_3_1_202020_1 - -# ###################### Setting up default value of HOST_ARCH ####################### -HOST_ARCH ?= x86 - -# #################### Checking if DEVICE in whitelist ############################ -ifneq ($(findstring xilinx_u250_xdma_201830_2, $(DEVICE)), xilinx_u250_xdma_201830_2) -$(warning [WARNING]: This project has not been tested for $(DEVICE). It may or may not work.) -endif - -# ######################## Setting up Project Variables ################################# -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L3/*}') -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XFLIB_DIR = $(XF_PROJ_ROOT) - -# ######################### Include environment variables in utils.mk #################### -include ./utils.mk -XDEVICE := $(call device2xsa, $(DEVICE)) -TEMP_DIR := _x_temp.$(TARGET).$(XDEVICE) -TEMP_REPORT_DIR := $(CUR_DIR)/reports/_x.$(TARGET).$(XDEVICE) -BUILD_DIR := build_dir.$(TARGET).$(XDEVICE) -BUILD_REPORT_DIR := $(CUR_DIR)/reports/_build.$(TARGET).$(XDEVICE) -EMCONFIG_DIR := $(BUILD_DIR) -XCLBIN_DIR := $(CUR_DIR)/$(BUILD_DIR) -export XCL_BINDIR = $(XCLBIN_DIR) - -# ######################### Setting up Host Variables ######################### -#Include Required Host Source Files -HOST_SRCS += $(XFLIB_DIR)/L3/tests/mlp/fcn_test.cpp - -CXXFLAGS += -I$(XFLIB_DIR)/L3/include/sw/mlp -CXXFLAGS += -I$(XFLIB_DIR)/../blas/L3/include/sw/xf_blas -LDFLAGS += -luuid -lxrt_coreutil - -ifeq ($(TARGET),sw_emu) -CXXFLAGS += -D SW_EMU_TEST -endif - -ifeq ($(TARGET),hw_emu) -CXXFLAGS += -D HW_EMU_TEST -endif - -# ######################### Host compiler global settings ############################ -CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++14 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE -CXXFLAGS += -fmessage-length=0 -CXXFLAGS += -I$(CUR_DIR)/src/ - -ifeq ($(HOST_ARCH), x86) -LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel -endif - -# ################### Setting package and image directory ####################### - -EXE_NAME := fcn_test.exe -EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) -HOST_ARGS := $(BUILD_DIR)/ data_64 1 64 1 - -# ##################### Kernel compiler global settings ########################## -VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps --optimize 2 -VPP_FLAGS += --hls.jobs 16 -VPP_LDFLAGS += --vivado.synth.jobs 16 --vivado.impl.jobs 16 -ifneq (,$(shell echo $(XPLATFORM) | awk '/u250/')) -VPP_FLAGS += --config $(CUR_DIR)/conn_u250.cfg -endif - -VPP_FLAGS += -I$(XFLIB_DIR)/L1/include/hw/mlp -VPP_FLAGS += -I$(XFLIB_DIR)/L2/include/hw/mlp -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw/xf_blas -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw/xf_blas/gemm -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L1/include/hw/xf_blas/helpers/utils -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L2/include/memKernel -VPP_FLAGS += -I$(XFLIB_DIR)/../blas/L2/include/memKernel/hw/xf_blas - -fcnKernel_VPP_FLAGS += --hls.clock 250000000:fcnKernel -VPP_LDFLAGS_fcn += --kernel_frequency 250 - - -# Kernel linker flags -VPP_LDFLAGS_fcn_temp := --config opts.cfg -VPP_LDFLAGS_fcn += $(VPP_LDFLAGS_fcn_temp) - -# ############################ Declaring Binary Containers ########################## - -BINARY_CONTAINERS += $(BUILD_DIR)/fcn.xclbin -BINARY_CONTAINER_fcn_OBJS += $(TEMP_DIR)/fcnKernel.xo - -# ######################### Setting Targets of Makefile ################################ - --include ./params.mk -.PHONY: all clean cleanall docs emconfig -all: check_vpp check_platform check_sysroot $(EXE_FILE) $(BINARY_CONTAINERS) emconfig - -.PHONY: host -host: check_xrt check_sysroot $(EXE_FILE) - -.PHONY: xclbin -xclbin: check_vpp check_sysroot $(BINARY_CONTAINERS) - -.PHONY: build -build: xclbin - -# ################ Setting Rules for Binary Containers (Building Kernels) ################ -$(TEMP_DIR)/fcnKernel.xo: $(XFLIB_DIR)/L2/src/hw/mlp/fcnKernel.cpp - $(ECHO) "Compiling Kernel: fcnKernel" - mkdir -p $(TEMP_DIR) - $(VPP) -c $(fcnKernel_VPP_FLAGS) $(VPP_FLAGS) -k fcnKernel -I'$(MKTJ0kD-?}zo%=~xq?yd;d-kBh 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 HuDkyM5DS?BZzcQ#%a=O7)nfMTeB3(Ftrr! zIPHNV>+yIbFqh8!d4p87;_=8_O>8}121_$%uq@9AD`keP+0#Js1{sFutHa1e1<}SF z=#uW=&ZiAqp=@3?b)9?W+<)x6@ayF3gqXTb#MkJP}#6aMSK8?i26lyIjR8XkB{x;j4iR;tC} zI}0GySOtUAB~&V%#TMzRl$qee&2cggT)&diiq!e!(ATg{<_LM?q`dc?1NJBP!xP5^ zeE;bnZ4R5xw+sB?&+Q%Jv82gdRA&Vp-kQAraT_%H?Sq5eCW7^v$tWqy7XPD`1Ai1g zgweC(Q8s=j1>GEgi(6GtS4&{k>P9MGW{$q!8B$4i1IVJJ9PnTb`u#EnZ zW4J`A&pGSW4^(1M1T#7lxn<{XaH6Un!a_^IK<>vH4sCGc!vDWynu~@$YT#zRRLpdr zi9fw`p$ow+RA?k&?U8GcZdXHHCfC5D(3<^D1@na^iYyC#NDJWd`aM zpNBJRROywTEBi!jz}aV$_@aFWh3>8<_ZKNBsk{NkTeopsikXn7t49eAC!J-}XY%$b z#@ITXN!sgxon0LH$gwVZAKnSiCb*%!nm1RO-lYBr0~&ZFr4J{*z))U{#k-JCxuo#N zzT;v|hy~2QUM+Mf=F>Mfi)oH|Bp(`>guhs)a+9X2*lqWtXfT+{WhwWC`8Au#&V3tp z=&$56nU-8RDHjxT9*f&F4%6%XiWnNAiJ>alU~trua?XTc<*hU!_J9`e^>|L_hrZ@l zYJMDbA9!kv2EUE5VD*`9{8Ul{C3qUVd@sV6Qxow}mJgR#HqZs(IoQ=`ak}$VZaw2J zjx0>a!cWSaZ(~7kdwOZ_*E4Xx?E|=W>K$x5SPS=5e4PVZ2ZfC%KPR_|$6@WXhom!6 z%3%wX@w=Y=ROgj|&e_Z8(``+j(&WzLXN6GYbw}D!x&Y_b+Ob*U3RLUe4V`&`c!M=~ zjmjP2a+p7+bXUO_G5^wsrB3`*sR86yi!a~!z5&Ws9f9SW^Jp&k;hMdU+`9;|sQm;O z=SH*g?d?KiX0AZNw;)X3LKcc^S*PJ3)X&g?+oyhkd3zkhqq*Ub!J}~aQ7L?uwF#%j zE#V>MNnCteMq|dyAV6-4>GzD$)LM%B?>Is6WdR$N{LslE8O_!w;ohHuFsoR^zj6@|#*gD!ZH~_WT)GD_zZ;?axjh|J+5)v*>XYoN~EM#0l$)Iaw@06)}Bf@e)RxNu3Cbh3O7JbO(gH2HC&+`2Cp*=*sEt1o^ZKD z5BoNwk+(PQ@Z5^OYkh?1rUjs{KMwIIFl-S?PpqOM`+1n*Zy{J+58(ER4zOzs_i;OfhN&BZ_ho^&%8~L z#s>479$k(NPeGk3IlUe8r2Z?NR5!2WvWiQpAP@g9nEo>tQ%`mZbMM!PW*V~vOgDh# z;e~Lt)PO5255Z}-Z&+{ZQgHRGzhV@nE$HRwiBV}9-1}V0qE3d`)YJ=eY-eFnW3w=< zRuA8+E8y$8D0+6t3O2r)k4d`mXnlGW-;K4!LHiB-yZ!{6Tc|;wlDlE|`-ME;E|zcV zbqlghV^_w7#`FFimiRb1myX>JW@+FkT>5Py|F~L>qFsY=rRfohf22g##_D|S$VI`- zLzU;Zm65JxxnR>V4aaUDqw?M)92U*l!NL_r!zF^JG!OhQ|3KA)>D+d$1GKXqfqkqg zCZx(J{7o`njrGS}DT`2}FV{J0;sYV+fG<|A-o(ZEi+TDXPhOE{gDVDSaqfgZ`07D4 z+vg|qSbGOKNn$wdg91+Q%z7~)UmCyuA^E=QfC#_SsbW7WKSV#dr)$4hQ5C;3J37B_yA?mLk|Do5=wrV&XAQqg zou#`kDto`$-K)L~=T|)KQnfuMhbBL#E|tC>a&bQ=LP5XZ)pb7;Ve-CCLxDaSi7~&R z`?EfeznH#M#M8ZPYJ0y{v(vsW(RIK1Uq`=(Ezmt^q7A>Za%VsEk3>I+vn0R5I2*r^ qG1R{M+5o>1SUW!GwQN3kEH1ykoxwg-Z&kjN$BDjGyJJ5Qq#!>Jv~lwQ diff --git a/hpc/L3/tests/mlp/data_64/mat_input_0_64.bin b/hpc/L3/tests/mlp/data_64/mat_input_0_64.bin deleted file mode 100644 index 17c55afe87ff44b33a8aa04341fc6fd7e9e7b73b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91136 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 SeI}LW$Z=*N4_QuE)c*iBOMIFD diff --git a/hpc/L3/tests/mlp/data_64/matb1_0.bin b/hpc/L3/tests/mlp/data_64/matb1_0.bin deleted file mode 100644 index 9432a8dff9..0000000000 --- a/hpc/L3/tests/mlp/data_64/matb1_0.bin +++ /dev/null @@ -1,2 +0,0 @@ -�����Ǿ�8��~����>s@ ?����H� � �z<{?"�'���B?4O>�a��)b�>��x��s]��I -��$�@~c��:?�����Id����=� y��S+���X?96��G -?5�x?���n:?��?QM&���m�P�_?jUg?wľ"^;>G���e?���=O?ŀB?�D=G,�> \ No newline at end of file diff --git a/hpc/L3/tests/mlp/data_64/matb3_0.bin b/hpc/L3/tests/mlp/data_64/matb3_0.bin deleted file mode 100644 index 08cfbd113c..0000000000 --- a/hpc/L3/tests/mlp/data_64/matb3_0.bin +++ /dev/null @@ -1 +0,0 @@ -�]�>�>��rs> \ No newline at end of file diff --git a/hpc/L3/tests/mlp/description.json b/hpc/L3/tests/mlp/description.json deleted file mode 100644 index 9dfba7252f..0000000000 --- a/hpc/L3/tests/mlp/description.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "name": "Xilinx XF_HPC FCN test", - "description": "", - "flow": "vitis", - "platform_whitelist": [ - "xilinx_u250_xdma_201830_2" - ], - "platform_blacklist": [], - "platform_type" : "pcie", - "gui": false, - "platform_properties": { - "u250": { - "host": { - "compiler": { - "symbols": [] - } - }, - "v++": { - "compiler": { - "cflags": [ - "--config PROJECT/conn_u250.cfg" - ] - } - } - } - }, - "launch": [ - { - "cmd_args": "BUILD/ data_64 1 64 1", - "name": "generic launch for all flows" - } - ], - "post_launch": [ - { - "launch_cmd": "make dump_config" - }], - "host": { - "host_exe": "fcn_test.exe", - "compiler": { - "sources": [ - "LIB_DIR/L3/tests/mlp/fcn_test.cpp" - ], - "includepaths": [ - "LIB_DIR/L3/include/sw/mlp", - "LIB_DIR/../blas/L3/include/sw/xf_blas" - ], - "symbols": [ - ] - }, - "linker": { - "options" : "-luuid -lxrt_coreutil" - } - }, - "v++": { - "compiler": { - "includepaths": [ - "LIB_DIR/L1/include/hw/mlp", - "LIB_DIR/L2/include/hw/mlp", - "LIB_DIR/../blas/L1/include/hw", - "LIB_DIR/../blas/L1/include/hw/xf_blas", - "LIB_DIR/../blas/L1/include/hw/xf_blas/gemm", - "LIB_DIR/../blas/L1/include/hw/xf_blas/helpers/utils", - "LIB_DIR/../blas/L2/include/memKernel", - "LIB_DIR/../blas/L2/include/memKernel/hw/xf_blas" - ] - } - }, - "containers": [ - { - "name" : "fcn", - "ldclflags" : "--config opts.cfg", - "frequency": 250, - "accelerators": [ - { - "name": "fcnKernel", - "location": "LIB_DIR/L2/src/hw/mlp/fcnKernel.cpp", - "frequency": 250 - } - ] - }], - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": 81920, - "max_time_min": 3600 - } - ], - "targets": [ - "vitis_hw_emu", - "vitis_hw" - ], - "category": "canary" - } -} diff --git a/hpc/L3/tests/mlp/fcn_test.cpp b/hpc/L3/tests/mlp/fcn_test.cpp deleted file mode 100644 index 447687b3d2..0000000000 --- a/hpc/L3/tests/mlp/fcn_test.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "xf_hpc_mlp.hpp" - -#include -#include -#include -#include -#include -#include - -#define IDX2R(i, j, ld) (((i) * (ld)) + (j)) - -typedef std::chrono::time_point TimePointType; - -double showTimeData(string p_Task, TimePointType& t1, TimePointType& t2) { - t2 = chrono::high_resolution_clock::now(); - chrono::duration l_durationSec = t2 - t1; - double l_timeMs = l_durationSec.count() * 1e3; - cout << p_Task << " " << fixed << setprecision(6) << l_timeMs << " msec\n"; - return l_timeMs; -} - -// read to 4k aligned memory -void readMatBin(char* mat, unsigned int size, string dataDir, string name, unsigned int eleSize) { - ifstream inFile; - inFile.open(dataDir + name + ".bin", ifstream::binary); - if (inFile.is_open()) { - inFile.read((char*)mat, eleSize * size); - inFile.close(); - } else { - cerr << "Could not find " << (dataDir + name + ".bin") << endl; - exit(1); - } -} - -bool compare(float* c, float* goldenC, int m, int n, int padded_n, float p_TolRel = 1e-3, float p_TolAbs = 1e-5) { - bool l_check = true; - int check_num = 0; - for (int row = 0; row < m; row++) { - for (int col = 0; col < n; col++) { - float l_ref = goldenC[IDX2R(row, col, n)]; - float l_result = c[IDX2R(row, col, padded_n)]; - float l_diffAbs = abs(l_ref - l_result); - float l_diffRel = l_diffAbs; - if (goldenC[IDX2R(row, col, n)] != 0) { - l_diffRel /= abs(l_ref); - } - bool check = (l_diffRel <= p_TolRel) || (l_diffAbs <= p_TolAbs); - if (!check) { - cout << "row " << row << " col " << col << "\n"; - cout << "golden result " << setprecision(10) << goldenC[IDX2R(row, col, n)] - << " is not equal to fpga result " << setprecision(10) << c[IDX2R(row, col, padded_n)] << "\n"; - - l_check = false; - check_num++; - } - } - } - cout << "number of mismatch" << check_num << "\n"; - return l_check; -} - -int getPaddedSize(int p_size, int p_minSize) { - return p_size + p_minSize - 1 - (p_size - 1) % p_minSize; -} - -float* fillMat(string dataDir, string name, int m, int n, int padded_m, int padded_n) { - float* mat; - float* padded_input; - posix_memalign((void**)&mat, 4096, m * n * sizeof(float)); - posix_memalign((void**)&padded_input, 4096, padded_m * padded_n * sizeof(float)); - memset(padded_input, 0, padded_m * padded_n * sizeof(float)); - - ifstream inFile; - inFile.open(dataDir + name + ".bin", ifstream::binary); - if (inFile.is_open()) { - inFile.read((char*)mat, m * n * sizeof(float)); - inFile.close(); - } else { - cerr << "Could not find " << (dataDir + name + ".bin") << endl; - exit(1); - } - - for (int row = 0; row < m; row++) { - for (int col = 0; col < n; col++) { - padded_input[IDX2R(row, col, padded_n)] = mat[IDX2R(row, col, n)]; - } - } - - free(mat); - - return padded_input; -} - -void sendInput(float* inputs[BLAS_numKernels], int input_size, int k0) { - bool check = true; - - for (int CU = 0; CU < BLAS_numKernels; CU++) { - // FPGA calls to create BO for inputs - check = xfhpcMalloc(input_size, k0, sizeof(float), inputs[CU], k0, CU); - if (!check) { - cout << "Malloc memory for input failed. \n"; - } - - // FPGA calls to send inputs to device - check = xfhpcSetMatrix(inputs[CU], CU); - if (!check) { - cout << "Set Matrix failed. \n"; - } - } -} - -void sendWeight(float* w0, - float* w1, - float* w2, - float* bias0, - float* bias1, - float* bias2, - int k0, - int n0, - int k1, - int n1, - int k2, - int n2) { - bool check = true; - - for (int j = 0; j < BLAS_numKernels; j++) { - // FPGA calls to create BO for weights - check = xfhpcMalloc(k0, n0, sizeof(float), w0, n0, j); - check = xfhpcMalloc(k1, n1, sizeof(float), w1, n1, j); - check = xfhpcMalloc(k2, n2, sizeof(float), w2, n2, j); - - // FPGA calls to send weights to device - check = xfhpcSetMatrix(w0, j); - check = xfhpcSetMatrix(w1, j); - check = xfhpcSetMatrix(w2, j); - - // FPGA calls to create BO for bias - check = xfhpcMalloc(1, n0, sizeof(float), bias0, n0, j); - check = xfhpcMalloc(1, n1, sizeof(float), bias1, n1, j); - check = xfhpcMalloc(1, n2, sizeof(float), bias2, n2, j); - - // FPGA calls to send bias to device - check = xfhpcSetMatrix(bias0, j); - check = xfhpcSetMatrix(bias1, j); - check = xfhpcSetMatrix(bias2, j); - } - - if (!check) { - cout << "Send weights and bias failed. \n"; - } -} - -float* executeInput(float* inputs[BLAS_numKernels], - float* w0, - float* w1, - float* w2, - float* bias0, - float* bias1, - float* bias2, - int k0, - int n0, - int k1, - int n1, - int k2, - int n2, - int batch_size, - double* executeTime, - double* totalSendTime, - double* totalGetTime) { - bool check = true; - - int input_size = batch_size / BLAS_numKernels; - - // create empty host memory for results - float *c0, *c1; - vector c2; - - posix_memalign((void**)&c0, 4096, input_size * n0 * sizeof(float)); - posix_memalign((void**)&c1, 4096, input_size * n1 * sizeof(float)); - memset(c0, 0, input_size * n0 * sizeof(float)); - memset(c1, 0, input_size * n1 * sizeof(float)); - - for (int j = 0; j < BLAS_numKernels; j++) { - float* tmp_c; - posix_memalign((void**)&tmp_c, 4096, input_size * n2 * sizeof(float)); - memset(tmp_c, 0, input_size * n2 * sizeof(float)); - c2.push_back(tmp_c); - } - - for (int j = 0; j < BLAS_numKernels; j++) { - // FPGA calls to create BO for results, since results don't have initial values, there is no need to send inputs - // to device - check = xfhpcMalloc(input_size, n0, sizeof(float), c0, n0, j); - check = xfhpcMalloc(input_size, n1, sizeof(float), c1, n1, j); - check = xfhpcMalloc(input_size, n2, sizeof(float), c2[j], n2, j); - - // FPGA calls to write instructions - - xfhpcFcn(input_size, n0, k0, 1, inputs[j], k0, w0, n0, 1, c0, n0, bias0, n0, 1, 0, 1, 0, j); - xfhpcFcn(input_size, n1, k1, 1, c0, k1, w1, n1, 1, c1, n1, bias1, n1, 1, 0, 1, 0, j); - xfhpcFcn(input_size, n2, k2, 1, c1, k2, w2, n2, 1, c2[j], n2, bias2, n2, 1, 0, 1, 1, j); - } - - // FPGA call to run all CUs - TimePointType l_tp_startrun_time = chrono::high_resolution_clock::now(); - TimePointType l_tp_execute_time; - - xfhpcExecuteAsync(BLAS_numKernels); - - *executeTime = *executeTime + showTimeData("xfhpcExecuteTime", l_tp_startrun_time, l_tp_execute_time); - - // allocate memory for reult - float* result_c; - posix_memalign((void**)&result_c, 4096, batch_size * n2 * sizeof(float)); - - for (int j = 0; j < BLAS_numKernels; j++) { - // FPGA call to get result in each CU from device - TimePointType l_tp_startget_time = chrono::high_resolution_clock::now(); - TimePointType l_tp_get_time; - - // FPGA call to get result in each CU from device - xfhpcGetByPointer(c2[j], j); - *totalGetTime = *totalGetTime + showTimeData("xfhpcGetTime " + to_string(j), l_tp_startget_time, l_tp_get_time); - - // combine them into one result_c - copy(c2[j], c2[j] + input_size * n2, result_c + j * input_size * n2); - } - - // FPGA calls to free B0s in device - for (int j = 0; j < BLAS_numKernels; j++) { - xfhpcFree(c2[j], j); - xfhpcFree(c0, j); - xfhpcFree(c1, j); - xfhpcFreeInstr(j); - free(c2[j]); - } - - free(c0); - free(c1); - - return result_c; -} - -int main(int argc, char** argv) { - unsigned int l_argIdx = 1; - string l_xclbinDir(argv[l_argIdx++]); - string l_dataDir(argv[l_argIdx++]); - l_dataDir = l_dataDir + "/"; - - double totalSendTime = 0; - double executeTime = 0; - double totalGetTime = 0; - - int l_model = atoi(argv[l_argIdx++]); - int l_batch_size = atoi(argv[l_argIdx++]); - int number_of_inputs = atoi(argv[l_argIdx++]); - - int l_k0 = 356; - int l_n0 = 30; - int l_k1 = 30; - int l_n1 = 20; - int l_k2 = 20; - int l_n2 = 3; - - int l_padded_batch_size = getPaddedSize(l_batch_size, BLAS_gemmMBlocks * BLAS_ddrWidth * BLAS_numKernels); - int l_padded_k0 = getPaddedSize(l_k0, BLAS_gemmKBlocks * BLAS_ddrWidth); - int l_padded_n0 = getPaddedSize(l_n0, BLAS_gemmNBlocks * BLAS_ddrWidth); - int l_padded_k1 = getPaddedSize(l_k1, max(BLAS_gemmKBlocks, BLAS_gemmNBlocks) * BLAS_ddrWidth); - int l_padded_n1 = getPaddedSize(l_n1, BLAS_gemmNBlocks * BLAS_ddrWidth); - int l_padded_k2 = getPaddedSize(l_k2, max(BLAS_gemmKBlocks, BLAS_gemmNBlocks) * BLAS_ddrWidth); - int l_padded_n2 = getPaddedSize(l_n2, BLAS_gemmNBlocks * BLAS_ddrWidth); - - // FPGA call to load xclbin and create device handle for each CU - - bool check = xfhpcCreate((l_xclbinDir + "/fcn.xclbin").c_str(), BLAS_numKernels); - if (!check) { - cout << "Create Handle failed. \n"; - } - vector w0s, w1s, w2s; - vector bias0s, bias1s, bias2s; - - for (int model = 0; model < l_model; model++) { - // create host memory for weights and bias read from data files - - float* w0 = fillMat(l_dataDir, "matW1_" + to_string(model), l_k0, l_n0, l_padded_k0, l_padded_n0); - float* w1 = fillMat(l_dataDir, "matW2_" + to_string(model), l_k1, l_n1, l_padded_k1, l_padded_n1); - float* w2 = fillMat(l_dataDir, "matW3_" + to_string(model), l_k2, l_n2, l_padded_k2, l_padded_n2); - - float* bias0 = fillMat(l_dataDir, "matb1_" + to_string(model), 1, l_n0, 1, l_padded_n0); - float* bias1 = fillMat(l_dataDir, "matb2_" + to_string(model), 1, l_n1, 1, l_padded_n1); - float* bias2 = fillMat(l_dataDir, "matb3_" + to_string(model), 1, l_n2, 1, l_padded_n2); - - w0s.push_back(w0); - w1s.push_back(w1); - w2s.push_back(w2); - - bias0s.push_back(bias0); - bias1s.push_back(bias1); - bias2s.push_back(bias2); - - TimePointType l_tp_start_time = chrono::high_resolution_clock::now(); - TimePointType l_tp_send_time; - - // FPGA call to send weights and bias - sendWeight(w0, w1, w2, bias0, bias1, bias2, l_padded_k0, l_padded_n0, l_padded_k1, l_padded_n1, l_padded_k2, - l_padded_n2); - - totalSendTime = totalSendTime + - showTimeData("xfhpcSendTime for model " + to_string(model), l_tp_start_time, l_tp_send_time); - } - - // create host memory for input and read from data file - - for (int inp = 0; inp < number_of_inputs; inp++) { - // create host memory for input read from data file - - float* input = fillMat(l_dataDir, "mat_input_" + to_string(inp) + "_" + to_string(l_batch_size), l_batch_size, - l_k0, l_padded_batch_size, l_padded_k0); - - int input_size = l_padded_batch_size / BLAS_numKernels; - float* inputs[BLAS_numKernels]; - - // split input into parts, each part for each CU - for (int CU = 0; CU < BLAS_numKernels; CU++) { - posix_memalign((void**)&inputs[CU], 4096, input_size * l_padded_k0 * sizeof(float)); - copy(input + CU * input_size * l_padded_k0, input + (CU + 1) * input_size * l_padded_k0, inputs[CU]); - } - - TimePointType l_tp_startSend_time = chrono::high_resolution_clock::now(); - TimePointType l_tp_send_input_time; - - // FPGA calls to send input to each CU - sendInput(inputs, input_size, l_padded_k0); - - totalSendTime = - totalSendTime + showTimeData("xfhpcSendTime for input", l_tp_startSend_time, l_tp_send_input_time); - - for (int model = 0; model < l_model; model++) { - // FPGA calls to get result_c (sizes are padded) - - float* result_c = - executeInput(inputs, w0s[model], w1s[model], w2s[model], bias0s[model], bias1s[model], bias2s[model], - l_padded_k0, l_padded_n0, l_padded_k1, l_padded_n1, l_padded_k2, l_padded_n2, - l_padded_batch_size, &executeTime, &totalSendTime, &totalGetTime); - - // read golden reference and compare with result_c - float* golden_c; - posix_memalign((void**)&golden_c, 4096, l_batch_size * l_n2 * sizeof(float)); - readMatBin((char*)golden_c, l_batch_size * l_n2, l_dataDir, - "mat_sigmoid_output_input_" + to_string(inp) + "_model_" + to_string(model), sizeof(float)); - compare(result_c, golden_c, l_batch_size, l_n2, l_padded_n2); - - free(result_c); - free(golden_c); - } - - for (int CU = 0; CU < BLAS_numKernels; CU++) { - xfhpcFree(inputs[CU]); - free(inputs[CU]); - } - free(input); - } - - double l_timeApiInMs = totalGetTime + totalSendTime + executeTime; - - cout << "DATA_CSV:,Traces,Inputs,L1,L2,Outputs,TimeApiSeconds,ExecutionSeconds,SendDataSeconds," - "GetOutputSeconds\n"; - cout << "DATA_CSV:," << l_batch_size << "," << l_padded_batch_size << "," << l_padded_n0 << "," << l_padded_n1 - << "," << l_padded_n2 << "," << l_timeApiInMs * 1e-3 << "," << executeTime * 1e-3 << "," - << totalSendTime * 1e-3 << "," << totalGetTime * 1e-3 << "\n"; - - for (int model = 0; model < l_model; model++) { - // FPGA call to free device memory of weights and bias - for (int j = 0; j < BLAS_numKernels; j++) { - xfhpcFree(w0s[model], j); - xfhpcFree(w1s[model], j); - xfhpcFree(w2s[model], j); - xfhpcFree(bias0s[model], j); - xfhpcFree(bias1s[model], j); - xfhpcFree(bias2s[model], j); - } - // free host memory of weights and bias - free(w0s[model]); - free(w1s[model]); - free(w2s[model]); - free(bias0s[model]); - free(bias1s[model]); - free(bias2s[model]); - } - // release device handle - xfhpcDestroy(BLAS_numKernels); - - return 0; -} diff --git a/hpc/L3/tests/mlp/opts.cfg b/hpc/L3/tests/mlp/opts.cfg deleted file mode 100644 index 2eecff33d6..0000000000 --- a/hpc/L3/tests/mlp/opts.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[vivado] -param=project.writeIntermediateCheckpoints=1 -prop=run.impl_1.STEPS.OPT_DESIGN.ARGS.DIRECTIVE=Explore -prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.IS_ENABLED=true -prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.ARGS.DIRECTIVE=AggressiveExplore -prop=run.impl_1.STEPS.ROUTE_DESIGN.ARGS.DIRECTIVE=Explore -prop=run.impl_1.{STEPS.ROUTE_DESIGN.ARGS.MORE OPTIONS}={-tns_cleanup} -prop=run.impl_1.STEPS.POST_ROUTE_PHYS_OPT_DESIGN.IS_ENABLED=true diff --git a/hpc/L3/tests/mlp/params.mk b/hpc/L3/tests/mlp/params.mk deleted file mode 100644 index 82c9762eaa..0000000000 --- a/hpc/L3/tests/mlp/params.mk +++ /dev/null @@ -1,78 +0,0 @@ -BLAS_ddrWidth=16 -BLAS_XddrWidth=16 -BLAS_argInstrWidth=1 - -BLAS_dataType=float -BLAS_gemmMBlocks=1 -BLAS_gemmKBlocks=2 -BLAS_gemmNBlocks=1 - -BLAS_argPipeline = 2 -BLAS_instructionSizeBytes = 64 -BLAS_numKernels = 4 - -BLAS_dataEqIntType = float -BLAS_XdataType = float -BLAS_argInstrWidth = 1 -BLAS_numInstr = 64 -TEST_MEMCPY = 0 -BLAS_CACHE = 1 -BLAS_XVEC = 1 - -activation = sigmoid - -#MACROS += -D MLP_TANSIG=1 -#CXXFLAGS += -D MLP_TANSIG=1 -#activation = tansig - -#MACROS += -D MLP_RELU=1 -#CXXFLAGS += -D MLP_RELU=1 -#activation = relu - -MACROS += -D TEST_MEMCPY=$(TEST_MEMCPY) \ - -D BLAS_instructionSizeBytes=$(BLAS_instructionSizeBytes) \ - -D BLAS_dataType=$(BLAS_dataType) \ - -D BLAS_dataEqIntType=$(BLAS_dataEqIntType) \ - -D BLAS_ddrWidth=$(BLAS_ddrWidth) \ - -D BLAS_argInstrWidth=$(BLAS_argInstrWidth) \ - -D BLAS_numInstr=$(BLAS_numInstr) \ - -D BLAS_argPipeline=$(BLAS_argPipeline) \ - -D BLAS_runTransp=0 \ - -D BLAS_runGemv=0 \ - -D BLAS_runGemm=0 \ - -D BLAS_runFcn=1 \ - -D BLAS_numKernels=${BLAS_numKernels}\ - -D BLAS_CACHE=${BLAS_CACHE}\ - -D BLAS_XVEC=${BLAS_XVEC} \ - -D BLAS_gemmMBlocks=${BLAS_gemmMBlocks} \ - -D BLAS_gemmKBlocks=${BLAS_gemmKBlocks} \ - -D BLAS_gemmNBlocks=${BLAS_gemmNBlocks} \ - -D BLAS_XdataType=$(BLAS_XdataType) \ - -D BLAS_XddrWidth=$(BLAS_XddrWidth) - -CXXFLAGS += -D BLAS_numKernels=$(BLAS_numKernels) \ - -D BLAS_gemmMBlocks=$(BLAS_gemmMBlocks) \ - -D BLAS_gemmKBlocks=$(BLAS_gemmKBlocks) \ - -D BLAS_gemmNBlocks=$(BLAS_gemmNBlocks) \ - -D BLAS_ddrWidth=$(BLAS_ddrWidth) \ - -D BLAS_runFcn=1 - - -VPP_FLAGS += ${MACROS} - -ifeq ($(TARGET),$(filter $(TARGET),hw_emu)) - CXXFLAGS += -lxrt_hwemu -else ifeq ($(TARGET),$(filter $(TARGET),sw_emu)) - CXXFLAGS += -lxrt_swemu -else - CXXFLAGS += -lxrt_core -endif - -CONFIG_INFO = $(shell echo ${MACROS} | sed 's/-D //g; s/ -Wno.*//') - -data_gen: - python $(XFLIB_DIR)/L2/src/python/mlp/data_gen.py --model 1 --batch 64 --activation $(activation) - -dump_config: - mkdir -p $(BUILD_DIR) - @echo ${CONFIG_INFO} | tr " " "\n" > ${BUILD_DIR}/config_info.dat diff --git a/hpc/L3/tests/mlp/run_test.sh b/hpc/L3/tests/mlp/run_test.sh deleted file mode 100755 index 77863faae6..0000000000 --- a/hpc/L3/tests/mlp/run_test.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -XCLBIN_PATH=$1 -MODEL_NUMBER=$2 -INPUT_NUMBER=$3 - -make host OUT_HW_DIR=$1 - -batch_list="204800" -logs=() - -for batch in $batch_list; do - python data_gen.py --model $2 --batch $batch --inputs $3 - ./build_dir.hw.xilinx_u250_xdma_201830_2/fcn_test.exe $1 data_$batch $2 $batch $3 | tee log-$batch.txt - logs="$logs log-$batch.txt" -done - - -egrep -h ^DATA_CSV $logs | head -1 > perf_QRes_20NN_Single.csv -egrep -h ^DATA_CSV $logs | grep -v Traces >> perf_QRes_20NN_Single.csv diff --git a/hpc/L3/tests/mlp/utils.mk b/hpc/L3/tests/mlp/utils.mk deleted file mode 100644 index 2ac520b27c..0000000000 --- a/hpc/L3/tests/mlp/utils.mk +++ /dev/null @@ -1,219 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -#+------------------------------------------------------------------------------- -# The following parameters are assigned with default values. These parameters can -# be overridden through the make command line -#+------------------------------------------------------------------------------- - -REPORT := no -PROFILE := no -DEBUG := no - -#'estimate' for estimate report generation -#'system' for system report generation -ifneq ($(REPORT), no) -VPP_LDFLAGS += --report estimate -VPP_LDFLAGS += --report system -endif - -#Generates profile summary report -ifeq ($(PROFILE), yes) -VPP_LDFLAGS += --profile_kernel data:all:all:all -endif - -#Generates debug summary report -ifeq ($(DEBUG), yes) -VPP_LDFLAGS += --dk protocol:all:all:all -endif - -#Check environment setup -ifndef XILINX_VITIS - XILINX_VITIS = /opt/xilinx/Vitis/$(TOOL_VERSION) - export XILINX_VITIS -endif -ifndef XILINX_XRT - XILINX_XRT = /opt/xilinx/xrt - export XILINX_XRT -endif - -#Checks for Device Family -ifeq ($(HOST_ARCH), aarch32) - DEV_FAM = 7Series -else ifeq ($(HOST_ARCH), aarch64) - DEV_FAM = Ultrascale -endif - -B_NAME = $(shell dirname $(XPLATFORM)) - -#Checks for Correct architecture -ifneq ($(HOST_ARCH), $(filter $(HOST_ARCH),aarch64 aarch32 x86)) -$(error HOST_ARCH variable not set, please set correctly and rerun) -endif - -#Checks for SYSROOT -check_sysroot: -ifneq ($(HOST_ARCH), x86) -ifndef SYSROOT - $(error SYSROOT ENV variable is not set, please set ENV variable correctly and rerun) -endif -endif - -#Checks for g++ -CXX := g++ -ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) -ifndef XILINX_VIVADO -$(error [ERROR]: g++ version too old. Please use 5.0 or above) -else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ -ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 -else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) -endif -$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) -endif -endif -else ifeq ($(HOST_ARCH), aarch64) -CXX := $(XILINX_VITIS)/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-g++ -else ifeq ($(HOST_ARCH), aarch32) -CXX := $(XILINX_VITIS)/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++ -endif - -#Check OS and setting env -OSDIST = $(shell lsb_release -i |awk -F: '{print tolower($$2)}' | tr -d ' \t' ) -OSREL = $(shell lsb_release -r |awk -F: '{print tolower($$2)}' |tr -d ' \t') - -ifeq ($(OSDIST), centos) -ifeq (7,$(shell echo $(OSREL) | awk -F. '{print tolower($$1)}' )) -CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 -endif -endif - -#Setting VPP -VPP := v++ - -#Cheks for aiecompiler - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) -ifeq ($(HOST_ARCH), x86) -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -else # aarch64 -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(SYSROOT)/usr/lib -else -LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) -endif -endif - -# check target -ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) -$(error TARGET is not sw_emu, hw_emu or hw) -endif - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE)/$(DEVICE).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE)/$(DEVICE).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE)/$(DEVICE).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif -#Check ends - -# device2xsa - create a filesystem friendly name from device name -# $(1) - full name of device -device2xsa = $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) - -# Cleaning stuff -RM = rm -f -RMDIR = rm -rf - -MV = mv -f -CP = cp -rf -ECHO:= @echo diff --git a/hpc/L3/tests/rtm2d/Makefile b/hpc/L3/tests/rtm2d/Makefile index 7216119d67..4e7411e4dc 100644 --- a/hpc/L3/tests/rtm2d/Makefile +++ b/hpc/L3/tests/rtm2d/Makefile @@ -106,6 +106,7 @@ CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++14 -O3 -Wall LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE CXXFLAGS += -fmessage-length=0 CXXFLAGS += -I$(CUR_DIR)/src/ +CXXFLAGS += $(XRT_CXXFLAGS) ifeq ($(HOST_ARCH), x86) LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel diff --git a/hpc/L3/tests/rtm2d/description.json b/hpc/L3/tests/rtm2d/description.json index db30a1ed2e..4a7e2431a7 100644 --- a/hpc/L3/tests/rtm2d/description.json +++ b/hpc/L3/tests/rtm2d/description.json @@ -3,11 +3,12 @@ "name": "Xilinx RTM Test", "description": "Xilinx RTM Test", "flow": "vitis", + "runtime": "XRT", "platform_type": "pcie", - "platform_whitelist": [ + "platform_allowlist": [ "u280" ], - "platform_blacklist": [ + "platform_blocklist": [ "other" ], "platform_properties": { diff --git a/hpc/L3/tests/rtm2d/preSysLink.tcl b/hpc/L3/tests/rtm2d/preSysLink.tcl new file mode 100644 index 0000000000..664d9964c1 --- /dev/null +++ b/hpc/L3/tests/rtm2d/preSysLink.tcl @@ -0,0 +1 @@ +upgrade_ip [get_bd_cells -filter {VLNV=~*hbm_memory_subsystem*}] diff --git a/hpc/L3/tests/rtm2d/utils.mk b/hpc/L3/tests/rtm2d/utils.mk index 20fe55b5fb..f1e21607c9 100644 --- a/hpc/L3/tests/rtm2d/utils.mk +++ b/hpc/L3/tests/rtm2d/utils.mk @@ -25,18 +25,22 @@ DEBUG := no #'estimate' for estimate report generation #'system' for system report generation ifneq ($(REPORT), no) -LDCLFLAGS += --report estimate -LDCLFLAGS += --report system +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) +VPP_LDFLAGS += -R 2 + #Generates profile summary report ifeq ($(PROFILE), yes) -LDCLFLAGS += --profile_kernel data:all:all:all +VPP_LDFLAGS += --profile_kernel data:all:all:all endif #Generates debug summary report ifeq ($(DEBUG), yes) -LDCLFLAGS += --dk protocol:all:all:all +VPP_LDFLAGS += --dk protocol:all:all:all endif #Check environment setup @@ -74,17 +78,17 @@ endif #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) -ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 8), 1) ifndef XILINX_VIVADO -$(error [ERROR]: g++ version older. Please use 5.0 or above) +$(error [ERROR]: g++ version too old. Please use 8.0 or above) else -CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/bin/g++ ifeq ($(LD_LIBRARY_PATH),) -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64 else -export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-8.3.0/lib64:$(LD_LIBRARY_PATH) endif -$(warning [WARNING]: g++ version older. Using g++ provided by the tool : $(CXX)) +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) endif endif else ifeq ($(HOST_ARCH), aarch64) @@ -93,13 +97,22 @@ else ifeq ($(HOST_ARCH), aarch32) CXX := $(XILINX_VITIS)/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++ endif -#Check OS and setting env +#Check OS and setting env for xrt c++ api OSDIST = $(shell lsb_release -i |awk -F: '{print tolower($$2)}' | tr -d ' \t' ) OSREL = $(shell lsb_release -r |awk -F: '{print tolower($$2)}' |tr -d ' \t') -ifeq ($(OSDIST), centos) +# for centos and redhat +ifneq ($(findstring centos,$(OSDIST)),) ifeq (7,$(shell echo $(OSREL) | awk -F. '{print tolower($$1)}' )) -CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 +ifeq ($(HOST_ARCH), x86) +XRT_CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 +endif +endif +else ifneq ($(findstring redhat,$(OSDIST)),) +ifeq (7,$(shell echo $(OSREL) | awk -F. '{print tolower($$1)}' )) +ifeq ($(HOST_ARCH), x86) +XRT_CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 +endif endif endif @@ -127,11 +140,19 @@ ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) endif export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) ifeq (,$(LD_LIBRARY_PATH)) LD_LIBRARY_PATH := $(XILINX_XRT)/lib else LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) endif +else # aarch64 +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib +else +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) +endif +endif # check target ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) @@ -209,3 +230,8 @@ RMDIR = rm -rf MV = mv -f CP = cp -rf ECHO:= @echo +ifneq (,$(shell echo $(XPLATFORM) | awk '/xilinx_u280_xdma_201920_3/')) +ifeq ($(TARGET), hw) +VPP_LDFLAGS += --advanced.param compiler.userPreSysLinkOverlayTcl=preSysLink.tcl +endif +endif