mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-15 13:40:29 +00:00
Compare commits
1 Commits
statsMonit
...
vcpkg-exam
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5be97fc12 |
@@ -23,6 +23,7 @@
|
||||
|
||||
cmake_minimum_required (VERSION 3.16)
|
||||
project (OpenAirInterface LANGUAGES C CXX)
|
||||
find_package(yaml-cpp CONFIG REQUIRED)
|
||||
|
||||
#########################################################
|
||||
# Base directories, compatible with legacy OAI building #
|
||||
@@ -473,7 +474,10 @@ target_link_libraries(CONFIG_LIB PRIVATE config_internals dl UTIL)
|
||||
|
||||
# CONFIG_LIB is a wrapper around a particular config implementation, default is
|
||||
# libconfig in params_libconfig below
|
||||
pkg_check_modules(libconfig REQUIRED libconfig)
|
||||
find_package(libconfig CONFIG) # attempt to find using vcpkg toolchain
|
||||
if (NOT libconfig_FOUND)
|
||||
pkg_check_modules(libconfig REQUIRED libconfig)
|
||||
endif()
|
||||
add_library(params_libconfig MODULE ${CONFIG_ROOTDIR}/libconfig/config_libconfig.c)
|
||||
target_include_directories(params_libconfig PRIVATE ${libconfig_INCLUDE_DIRS})
|
||||
target_link_libraries(params_libconfig PRIVATE config_internals ${libconfig_LIBRARIES})
|
||||
@@ -2457,7 +2461,10 @@ if(ENABLE_TESTS)
|
||||
# meta-target: each test is supposed to add_dependencies(tests ${NEWTEST})
|
||||
# then, it is possible to build and execute all tests using "ninja tests && ctest"
|
||||
add_custom_target(tests)
|
||||
find_package(GTest)
|
||||
find_package(GTest CONFIG)
|
||||
if (NOT GTest_FOUND)
|
||||
find_package(GTest)
|
||||
endif()
|
||||
if (NOT GTest_FOUND)
|
||||
message(STATUS "GTest package not found, will download googletest automatically. To prevent that install google test on your system (libgtest-dev)")
|
||||
include(FetchContent)
|
||||
|
||||
18
CMakePresets.json
Normal file
18
CMakePresets.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": 2,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/cmake_targets/ran-build/build"
|
||||
},
|
||||
{
|
||||
"name": "vcpkg",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4,7 +4,6 @@ To create graphs and pickle from runtime statistics in L1,MAC,RRC,PDCP files
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
from datetime import datetime,timezone,timedelta
|
||||
import shlex
|
||||
import re
|
||||
import sys
|
||||
@@ -13,7 +12,6 @@ import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import yaml
|
||||
import os
|
||||
import copy
|
||||
|
||||
|
||||
class StatMonitor():
|
||||
@@ -22,85 +20,28 @@ class StatMonitor():
|
||||
self.d = yaml.load(file)
|
||||
for node in self.d:#so far we have enb or gnb as nodes
|
||||
for metric_l1 in self.d[node]: #first level of metric keys
|
||||
if metric_l1=="ue": #graph is a reserved word to configure graph paging, so it is disregarded
|
||||
if metric_l1!="graph": #graph is a reserved word to configure graph paging, so it is disregarded
|
||||
if self.d[node][metric_l1] is None:#first level is None -> create array
|
||||
self.d[node][metric_l1]=[]
|
||||
else: #first level is not None -> there is a second level -> create array
|
||||
for metric_l2 in self.d[node][metric_l1]:
|
||||
self.d[node][metric_l1][metric_l2]=[]
|
||||
self.d[node]['rntis']={}
|
||||
|
||||
|
||||
|
||||
def process_gnb (self,node_type,output):
|
||||
rnti='65535'
|
||||
bp_enable = False
|
||||
ts = time.gmtime(0) #Bad, but just creating a date
|
||||
for line in output:
|
||||
tmp=line.decode("utf-8")
|
||||
result=re.match(r'^.*\bUE RNTI ([a-zA-Z0-9]+) CU-UE-ID',tmp)
|
||||
result=re.match(r'^.*\bdlsch_rounds\b ([0-9]+)\/([0-9]+).*\bdlsch_errors\b ([0-9]+)',tmp)
|
||||
if result is not None:
|
||||
rnti=result.group(1)
|
||||
if not rnti in self.d['gnb']['rntis']:
|
||||
print("Found new RNTI: "+tmp)
|
||||
self.d['gnb']['rntis'][rnti] = copy.deepcopy(self.d['gnb']['ue'])
|
||||
#bp_enable = True
|
||||
continue
|
||||
|
||||
if bp_enable:
|
||||
print(tmp)
|
||||
breakpoint()
|
||||
result=re.match(r'^.*\bdlsch_rounds\b ([0-9]+)\/([0-9]+).*\bdlsch_errors\b ([0-9]+).*\bBLER\b ([0-9]+[.][0-9]+) \bMCS\b \([0-1]\) ([0-9]+)',tmp)
|
||||
self.d[node_type]['dlsch_err'].append(int(result.group(3)))
|
||||
percentage=float(result.group(2))/float(result.group(1))
|
||||
self.d[node_type]['dlsch_err_perc_round_1'].append(percentage)
|
||||
result=re.match(r'^.*\bulsch_rounds\b ([0-9]+)\/([0-9]+).*\bulsch_errors\b ([0-9]+)',tmp)
|
||||
if result is not None:
|
||||
self.d[node_type]['rntis'][rnti]['dlsch_err'].append(int(result.group(3)))
|
||||
try:
|
||||
percentage=100.0*float(result.group(2))/float(result.group(1))
|
||||
except ZeroDivisionError:
|
||||
percentage=0.0
|
||||
self.d[node_type]['rntis'][rnti]['dlsch_err_perc_round_1'].append(percentage)
|
||||
self.d[node_type]['rntis'][rnti]['dlbler'].append(float(result.group(4)))
|
||||
self.d[node_type]['rntis'][rnti]['dlmcs'].append(int(result.group(5)))
|
||||
result=re.match(r'^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{6}Z)',tmp)
|
||||
if result is not None:
|
||||
ts = datetime.strptime(result.group(1),'%Y-%m-%d %H:%M:%S.%fZ')
|
||||
if sys.version_info[0] == 3 and sys.version_info[1] < 11:
|
||||
ts = ts.replace(tzinfo=timezone.utc)
|
||||
self.d[node_type]['rntis'][rnti]['timestamp'].append(ts)
|
||||
continue
|
||||
|
||||
result=re.match(rf'^.*\b{rnti}\b: \bMAC\b.*\bTX\b +([0-9]+).*\bRX\b +([0-9]+)',tmp)
|
||||
if result is not None:
|
||||
if len(self.d[node_type]['rntis'][rnti]['dlsch_mbps']) == 0:
|
||||
self.d[node_type]['rntis'][rnti]['dlsch_mbps'].append(0)
|
||||
self.d[node_type]['rntis'][rnti]['ulsch_mbps'].append(0)
|
||||
self.d[node_type]['rntis'][rnti]['dlsch_prev_bytes'].append(float(result.group(1)))
|
||||
self.d[node_type]['rntis'][rnti]['ulsch_prev_bytes'].append(float(result.group(2)))
|
||||
else :
|
||||
prev = self.d[node_type]['rntis'][rnti]['dlsch_prev_bytes'].pop()
|
||||
#8 bits per byte, 10^20 Bits per Mbps, subtract bler
|
||||
times =self.d[node_type]['rntis'][rnti]['timestamp'][-2:]
|
||||
#delta_t = times[1]-times[0]
|
||||
delta_t = timedelta(milliseconds=1280)
|
||||
delta = (float(result.group(1)) - prev)*2**3/2**20*(1.0- self.d[node_type]['rntis'][rnti]['dlbler'][-1])/delta_t.total_seconds()
|
||||
self.d[node_type]['rntis'][rnti]['dlsch_mbps'].append(delta)
|
||||
self.d[node_type]['rntis'][rnti]['dlsch_prev_bytes'].append(float(result.group(1)))
|
||||
|
||||
prev = self.d[node_type]['rntis'][rnti]['ulsch_prev_bytes'].pop()
|
||||
#8 bites per byte, 10^20 bits per mbps, subtract bler
|
||||
delta = (float(result.group(2)) - prev)*2**3/2**20*(1.0-self.d[node_type]['rntis'][rnti]['ulbler'][-1])/delta_t.total_seconds()
|
||||
self.d[node_type]['rntis'][rnti]['ulsch_mbps'].append(delta)
|
||||
self.d[node_type]['rntis'][rnti]['ulsch_prev_bytes'].append(float(result.group(2)))
|
||||
continue
|
||||
|
||||
result=re.match(r'^.*\bulsch_rounds\b ([0-9]+)\/([0-9]+).*\bulsch_errors\b ([0-9]+).*\bBLER\b ([0-9]+[.][0-9]+) \bMCS\b \([0-1]\) ([0-9]+)',tmp)
|
||||
if result is not None:
|
||||
self.d[node_type]['rntis'][rnti]['ulsch_err'].append(int(result.group(3)))
|
||||
try:
|
||||
percentage=100.0*float(result.group(2))/float(result.group(1))
|
||||
except ZeroDivisionError:
|
||||
percentage=0.0
|
||||
self.d[node_type]['rntis'][rnti]['ulsch_err_perc_round_1'].append(percentage)
|
||||
self.d[node_type]['rntis'][rnti]['ulbler'].append(float(result.group(4)))
|
||||
self.d[node_type]['rntis'][rnti]['ulmcs'].append(int(result.group(5)))
|
||||
continue
|
||||
self.d[node_type]['ulsch_err'].append(int(result.group(3)))
|
||||
percentage=float(result.group(2))/float(result.group(1))
|
||||
self.d[node_type]['ulsch_err_perc_round_1'].append(percentage)
|
||||
|
||||
for k in self.d[node_type]['rt']:
|
||||
result=re.match(rf'^.*\b{k}\b:\s+([0-9\.]+) us;\s+([0-9]+);\s+([0-9\.]+) us;',tmp)
|
||||
@@ -120,14 +61,18 @@ class StatMonitor():
|
||||
|
||||
|
||||
def collect(self,testcase_id,node_type):
|
||||
if node_type=='enb':
|
||||
files = ["L1_stats.log", "MAC_stats.log", "PDCP_stats.log", "RRC_stats.log"]
|
||||
else: #'gnb'
|
||||
files = ["nrL1_stats.log", "nrMAC_stats.log", "nrPDCP_stats.log", "nrRRC_stats.log"]
|
||||
#append each file's contents to another file (prepended with CI-) for debug
|
||||
for f in self.d[node_type]['files']:
|
||||
for f in files:
|
||||
if os.path.isfile(f):
|
||||
cmd = 'cat '+ f + ' >> CI-'+testcase_id+'-'+f
|
||||
subprocess.Popen(cmd,shell=True)
|
||||
#join the files for further processing
|
||||
cmd='cat '
|
||||
for f in self.d[node_type]['files']:
|
||||
for f in files:
|
||||
if os.path.isfile(f):
|
||||
cmd += f+' '
|
||||
process=subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
|
||||
@@ -141,54 +86,34 @@ class StatMonitor():
|
||||
def graph(self,testcase_id, node_type):
|
||||
for page in self.d[node_type]['graph']:#work out a set a graphs per page
|
||||
col = 1
|
||||
figure, axis = plt.subplots(len(self.d[node_type]['graph'][page]), col ,figsize=(10, 10), sharex=True)
|
||||
figure, axis = plt.subplots(len(self.d[node_type]['graph'][page]), col ,figsize=(10, 10))
|
||||
i=0
|
||||
for m in self.d[node_type]['graph'][page]:#metric may refer to 1 level or 2 levels
|
||||
metric_path=m.split('.')
|
||||
metric_l1=metric_path[0]
|
||||
if metric_path[0]=='ue':
|
||||
metric_l2=metric_path[1]
|
||||
major_ticks = np.arange(0, 10, 1)
|
||||
for rnti in self.d[node_type]['rntis']:
|
||||
tput = ''
|
||||
if 'mbps' in metric_l2:
|
||||
n = self.d[node_type]['test_params']['duration']
|
||||
top_n = (sorted(self.d[node_type]['rntis'][rnti][metric_l2])[-n:])
|
||||
tput = str(round(sum(top_n)/n,1))
|
||||
tput = ' '+tput+' Mbps'
|
||||
axis[i].plot(self.d[node_type]['rntis'][rnti][metric_l2],label=rnti+tput)
|
||||
major_ticks = np.arange(0, len(self.d[node_type]['rntis'][rnti][metric_l2])+1, 1)
|
||||
axis[i].set_xticks(major_ticks)
|
||||
axis[i].set_xticklabels([])
|
||||
axis[i].grid(axis='y')
|
||||
axis[i].legend(loc='center left')
|
||||
axis[i].set_xlabel('time (s)')
|
||||
axis[i].set_ylabel(metric_l2)
|
||||
|
||||
else:
|
||||
if len(metric_path)==1:#1 level
|
||||
major_ticks = np.arange(0, len(self.d[node_type][metric_l1])+1, 1)
|
||||
axis[i].set_xticks(major_ticks)
|
||||
axis[i].set_xticklabels([])
|
||||
axis[i].plot(self.d[node_type][metric_l1],marker='o')
|
||||
axis[i].set_xlabel('time')
|
||||
axis[i].set_ylabel(metric_l1)
|
||||
axis[i].set_title(metric_l1)
|
||||
|
||||
else:#2 levels
|
||||
metric_l2=metric_path[1]
|
||||
major_ticks = np.arange(0, len(self.d[node_type][metric_l1][metric_l2])+1, 1)
|
||||
axis[i].set_xticks(major_ticks)
|
||||
axis[i].set_xticklabels([])
|
||||
axis[i].plot(self.d[node_type][metric_l1][metric_l2],marker='o')
|
||||
axis[i].set_xlabel('time')
|
||||
axis[i].set_ylabel(metric_l2)
|
||||
axis[i].set_title(metric_l2)
|
||||
if len(metric_path)==1:#1 level
|
||||
metric_l1=metric_path[0]
|
||||
major_ticks = np.arange(0, len(self.d[node_type][metric_l1])+1, 1)
|
||||
axis[i].set_xticks(major_ticks)
|
||||
axis[i].set_xticklabels([])
|
||||
axis[i].plot(self.d[node_type][metric_l1],marker='o')
|
||||
axis[i].set_xlabel('time')
|
||||
axis[i].set_ylabel(metric_l1)
|
||||
axis[i].set_title(metric_l1)
|
||||
|
||||
else:#2 levels
|
||||
metric_l1=metric_path[0]
|
||||
metric_l2=metric_path[1]
|
||||
major_ticks = np.arange(0, len(self.d[node_type][metric_l1][metric_l2])+1, 1)
|
||||
axis[i].set_xticks(major_ticks)
|
||||
axis[i].set_xticklabels([])
|
||||
axis[i].plot(self.d[node_type][metric_l1][metric_l2],marker='o')
|
||||
axis[i].set_xlabel('time')
|
||||
axis[i].set_ylabel(metric_l2)
|
||||
axis[i].set_title(metric_l2)
|
||||
i+=1
|
||||
|
||||
plt.tight_layout()
|
||||
#save as png
|
||||
#plt.show()
|
||||
plt.savefig(node_type+'_stats_monitor_'+testcase_id+'_'+page+'.png')
|
||||
|
||||
|
||||
@@ -203,13 +128,11 @@ if __name__ == "__main__":
|
||||
CMD='ps aux | grep modem | grep -v grep'
|
||||
process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
|
||||
output = process.stdout.readlines()
|
||||
while True:
|
||||
while len(output)!=0 :
|
||||
mon.collect(testcase_id,node)
|
||||
process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
|
||||
output = process.stdout.readlines()
|
||||
time.sleep(1)
|
||||
if len(output)==0 :
|
||||
break;
|
||||
print('Process stopped')
|
||||
with open(node+'_stats_monitor.pickle', 'wb') as handle:
|
||||
pickle.dump(mon.d, handle, protocol=pickle.HIGHEST_PROTOCOL)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
enb :
|
||||
files: ["L1_stats.log", "MAC_stats.log", "PDCP_stats.log", "RRC_stats.log"]
|
||||
test_params:
|
||||
duration: 10 #Number of samples to average over for throughput
|
||||
PHR:
|
||||
bler:
|
||||
mcsoff:
|
||||
@@ -14,25 +11,10 @@ enb :
|
||||
mcs:
|
||||
|
||||
gnb :
|
||||
#files: ["nrL1_stats.log", "nrMAC_stats.log", "nrPDCP_stats.log", "nrRRC_stats.log"]
|
||||
files: ["oai.log"]
|
||||
test_params:
|
||||
duration: 10 #Number of samples to average over for throughput
|
||||
ue :
|
||||
timestamp:
|
||||
dlsch_bler:
|
||||
dlsch_mbps:
|
||||
dlsch_prev_bytes:
|
||||
dlmcs:
|
||||
dlbler:
|
||||
dlsch_err:
|
||||
dlsch_err_perc_round_1:
|
||||
ulmcs:
|
||||
ulbler:
|
||||
ulsch_mbps:
|
||||
ulsch_prev_bytes:
|
||||
ulsch_err:
|
||||
ulsch_err_perc_round_1:
|
||||
dlsch_err:
|
||||
dlsch_err_perc_round_1:
|
||||
ulsch_err:
|
||||
ulsch_err_perc_round_1:
|
||||
rt :
|
||||
feprx:
|
||||
feptx_prec:
|
||||
@@ -47,14 +29,10 @@ gnb :
|
||||
Slot Indication:
|
||||
graph :
|
||||
page1:
|
||||
ue.dlsch_mbps:
|
||||
#ue.dlsch_err:
|
||||
ue.dlmcs:
|
||||
ue.dlsch_err_perc_round_1:
|
||||
ue.ulsch_mbps:
|
||||
ue.ulmcs:
|
||||
#ue.ulsch_err:
|
||||
ue.ulsch_err_perc_round_1:
|
||||
dlsch_err:
|
||||
dlsch_err_perc_round_1:
|
||||
ulsch_err:
|
||||
ulsch_err_perc_round_1:
|
||||
page2:
|
||||
rt.feprx:
|
||||
rt.feptx_prec:
|
||||
|
||||
14
vcpkg-configuration.json
Normal file
14
vcpkg-configuration.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"default-registry": {
|
||||
"kind": "git",
|
||||
"baseline": "7a57b42f959ad138a5283477fe2e6c97a7cb852f",
|
||||
"repository": "https://github.com/microsoft/vcpkg"
|
||||
},
|
||||
"registries": [
|
||||
{
|
||||
"kind": "artifact",
|
||||
"location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip",
|
||||
"name": "microsoft"
|
||||
}
|
||||
]
|
||||
}
|
||||
8
vcpkg.json
Normal file
8
vcpkg.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"yaml-cpp", "gtest", "libconfig"
|
||||
],
|
||||
"overrides": [
|
||||
{ "name": "gtest", "version": "1.12.1" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user