[docs]classAdapter(network_gym_client.adapter.Adapter):"""rmcat env adapter. Args: Adapter (network_gym_client.adapter.Adapter): base class. """def__init__(self,config_json):"""Initialize the adapter. Args: config_json (json): the configuration file """super().__init__(config_json)self.env=Path(__file__).resolve().parent.nameself.num_features=3self.size_per_feature=int(self.config_json['env_config']['nada_flows'])ifconfig_json['env_config']['env']!=self.env:sys.exit("[ERROR] wrong environment Adapter. Configured environment: "+str(config_json['env_config']['env'])+" != Launched environment: "+str(self.env))FILE_PATH=Path(__file__).parent#Append the bw_trace to json file.data={}# Open a csv reader called DictReaderwithopen(FILE_PATH/config_json['env_config']['bw_trace_file'],encoding='utf-8')ascsvf:csvReader=csv.DictReader(csvf)# Convert each row into a dictionary # and add it to dataforrowsincsvReader:forkey,valueinrows.items():ifkeynotindata:data[key]=[float(value)]else:data[key].append(float(value))config_json['env_config']['bw_trace']=datadefget_action_space(self):"""Get action space for the rmcat env. Returns: spaces: action spaces """RMCAT_CC_DEFAULT_RMIN=150000# in bps: 150Kbps RMCAT_CC_DEFAULT_RMAX=1500000.# in bps: 1.5Mbpsreturnspaces.Box(low=RMCAT_CC_DEFAULT_RMIN,high=RMCAT_CC_DEFAULT_RMAX,shape=(self.size_per_feature,),dtype=np.float32)#consistent with the get_observation function.defget_observation_space(self):"""Get the observation space for rmcat env. Returns: spaces: observation spaces """returnspaces.Box(low=0,high=1000,shape=(self.num_features,self.size_per_feature),dtype=np.float32)defget_observation(self,df):"""Prepare observation for rmcat env. This function should return the same number of features defined in the :meth:`get_observation_space`. Args: df (pd.dataframe): network stats measurement Returns: spaces: observation spaces """#print (df)row_loglen=Nonerow_qdel=Nonerow_rtt=Nonerow_ploss=Nonerow_plr=Nonerow_xcurr=Nonerow_rrate=Nonerow_srate=Nonertt_value=np.empty(self.size_per_feature,dtype=object)xcurr_value=np.empty(self.size_per_feature,dtype=object)rrate_value=np.empty(self.size_per_feature,dtype=object)forindex,rowindf.iterrows():ifrow['source']=='rmcat':ifrow['name']=='loglen':row_loglen=rowelifrow['name']=='qdel':row_qdel=rowelifrow['name']=='rtt':row_rtt=rowrtt_value=row['value']self.action_data_format=rowelifrow['name']=='ploss':row_ploss=rowelifrow['name']=='plr':row_plr=rowelifrow['name']=='xcurr':row_xcurr=rowxcurr_value=row['value']elifrow['name']=='rrate':row_rrate=rowrrate_value=row['value']elifrow['name']=='srate':row_srate=rowself.wandb_log_buffer_append(self.df_to_dict(row_loglen))self.wandb_log_buffer_append(self.df_to_dict(row_qdel))self.wandb_log_buffer_append(self.df_to_dict(row_rtt))self.wandb_log_buffer_append(self.df_to_dict(row_ploss))self.wandb_log_buffer_append(self.df_to_dict(row_plr))self.wandb_log_buffer_append(self.df_to_dict(row_xcurr))self.wandb_log_buffer_append(self.df_to_dict(row_rrate))self.wandb_log_buffer_append(self.df_to_dict(row_srate))observation=np.vstack([rtt_value,rrate_value,xcurr_value])# print('Observation --> ' + str(observation))returnobservationdefget_policy(self,action):"""Prepare policy for the rmcat env. Args: action (spaces): action from the RL agent Returns: json: network policy """# you may also check other constraints for action... e.g., min, max.policy1=json.loads(self.action_data_format.to_json())policy1["name"]="srate"policy1["value"]=action.tolist()# print('Action --> ' + str(policy1))returnpolicy1defget_reward(self,df):"""Prepare reward for the rmcat env. Args: df (pd.DataFrame): network stats Returns: spaces: reward spaces """#TODO: add a reward function for you rmcat envreward=0# send info to wandbself.wandb_log_buffer_append({"reward":reward})returnreward