acsicuib / YAFS

Yet Another Fog Simulator (YAFS)
MIT License
98 stars 72 forks source link

Creating large number of messages and nodes #60

Closed sanket099 closed 2 years ago

sanket099 commented 2 years ago

Hi @wisaaco , Is there a way, to create large nodes in topology and messages automatically with some function. For example, we make messages by writing lines manually currently. Is there a function which can help to create large number of messages

wisaaco commented 2 years ago

Dear @sanket099 ,

When I model large infrastructure topologies, I use the networkx library to create random graphs and also use it to add the attributes of the yafs nodes. When I get the graph and attributes, I prefer to store the topology in JSON format since the simulations of a study are always with the same topology. I avoid running this code in each test.

I attach a basic example:

import networkx as nx
import numpy as np

G = nx.generators.random_graphs.barabasi_albert_graph(100,1,seed=23) #there are more graph generators in NX
#G = nx.generators.full_rary_tree(4,200)

pos= nx.kamada_kawai_layout(G)
pos = nx.rescale_layout_dict(pos,20)
nx.draw(G)

deg = nx.degree(G)
cent = nx.betweenness_centrality(G)
root = np.argmax(cent.values()) 

levels = nx.single_source_shortest_path_length(G,root)
nx.set_node_attributes(G,values=levels,name="level")
nLevel = max(levels.values())+1

edges = [x for (x,d) in deg if d==1]

# JSON GENERATION 
entities = [] #nodes
for n in G.nodes():
    #basic attributes
    hwr = (nLevel-levels[n])*10 #capacity
    shape = "(%i,%i)"%((nLevel-levels[n]),10) # from our last study (MARIO paper)
    ipt = (nLevel-levels[n])*1000 #MIPS
    entities.append(dict({"id":n,"name":0,"IPT":ipt,"HwReqs":hwr,"WATT":1,"RAM":1,"shape":shape}))

links = [] #edges
for (s,d) in G.edges():
    lat = (levels[s]+1)*2 #latency
    links.append(dict({"PR":lat,"s":s,"BW":1,"d":d}))

with open("topology.json","w") as f:
    f.write("{\"link\":[\n")
    for link in links[:-1]:
        f.write(str(link).replace("'","\"")+",\n")
    f.write(str(links[-1]).replace("'","\""))
    f.write("],\n\"entity\":[\n")
    for n in entities[:-1]:
        f.write(str(n).replace("'","\"")+",\n")
    f.write(str(entities[-1]).replace("'","\""))
    f.write("]}")        

# Visualization: use Gephi application to open the next file
nx.write_gexf(G,"topo.gexf")

By "message generation", do you mean request generation by users? In this case, I have a basic function to generate random positions of users along the topology. This is an example:

def generate_random_users_and_their_placements(maxNumberOfUsers,edgesNodes = None):
    numberOfUsers = np.random.randint(1, maxNumberOfUsers)
    users = []
    for i in range(numberOfUsers):
        user = {}
        app = np.random.randint(1, len(apps) + 1)
        user["app"] = app
        user["message"] = "M.USER.APP.%i" % app
        user["start"] = 0
        user["lambda"] = np.random.randint(20,300)
        if edgesNodes == None:
            user["id_resource"] = np.random.randint(0, len(t.G.nodes()))
        else:
            user["id_resource"] = np.random.choice(edgesNodes,1)[0]
        users.append(user)
    return users

## and the code to insert them in the simulator

# Initial user placement & User request distribution & User deployment for each app
dataPopulation = generate_random_users_and_their_placements(maxNumberOfUsers)
for aName in apps.keys():
    data = []
    for element in dataPopulation:
        if element['app'] == aName:
            data.append(element)
    # For each application we create a DES process who introduce the users in the system
    # Each DES follows a distribution, in this case all these apps starts at the same simulation time: 1
    distribution = deterministic_distribution(name="DET", time=1)
    pop_app = DynamicWorkload(name="Dynamic_%s" % aName, data=data, iteration=state, activation_dist=distribution)
    s.deploy_pop(apps[aName], pop_app)

Best