1 /*! \page bindings Bindings
3 \htmlinclude .bindings.doc.toc
5 \section bindings_start Available bindings
7 \subsection bindings_binding_lua Lua Binding
8 Most of Simgrid modules require a good level in C programming, since simgrid is used to be as standard C library.
9 Sometime users prefer using some kind of « easy scripts » or a language easier to code with, for their works,
10 which avoid dealing with C errors, and sometime an important gain of time.
11 Besides Java Binding, Lua and Ruby bindings are available since version 3.4 of Simgrid
12 for MSG Module, and we are currenlty working on bindings for other modules.
15 \subsubsection bindings_binding_lua_about What is lua ?
16 Lua is a lightweight, reflective, imperative and functional programming language,
17 designed as a scripting language with extensible semantics as a primary goal (see official web site <a href="http://www.lua.org">here</a>).
18 \subsubsection bindings_binding_lua_why Why lua ?
19 Lua is a fast, portable and powerful script language, quite simple to use for developpers.
20 it combines procedural features with powerful data description facilities,
21 by using a simple, yet powerful, mechanism of tables.
22 Lua has a relatively simple C API compared to other scripting languages,
23 and accordingly it provides a robust, easy to use it.
24 \subsubsection bindings_binding_lua_simgrid How to use lua in Simgrid ?
25 Actually, the use of lua in Simgrid is quite simple, you have just to follow the same steps as coding with C in Simgird :
26 - Coding functions coresponding to each process
27 - loading the platforme/deployment XML file that describe the environment of simulation
28 - and … Running the Simulation.
30 \dontinclude lua/masterslave/master.lua
31 \subsubsection bindings_binding_lua_example_master_slave Master/Slave Example
35 we mainly use simgrid.Task.new(task_name,computation_size,communication_size) to create our MSG Task,
36 then simgrid.Task.send(task,alias) to send it.
37 we use also simgrid.Task.name(task), to get the task's name.
39 \dontinclude lua/masterslave/slave.lua
42 Here, we see the use of simgrid.Task.recv(alias) to receive a task with a specific alias,
43 this function return directly the task recevied.
45 \dontinclude lua/masterslave/master_slave.lua
46 \li Set Environmenet and run application
47 \until simgrid.clean()
49 \subsubsection bindings_binding_lua_example_data Exchanging Data
50 You can also exchange data between Process using lua. for that, you have to deal with lua task as a table,
51 since lua is based itself on a mechanism of tables,
52 so you can exchange any kind of data (tables, matrix, strings,…) between process via tasks.
56 task = simgrid.Task.new("data_task",task_comp,task_comm);
57 task['matrix'] = my_matrix;
58 task['table'] = my_table;
59 task['message'] = "Hello from (Lua || Simgrid ) !! "
61 simgrid.Task.send(task,alias)
63 After creating task, we associate to it various kind of data with a specific key (string in this case)
64 to distinguish between data variables. The receiver will use this key to access easily to datas.
69 task = simgrid.Task.recv(alias);
70 sender_matrix = task['matrix'];
71 sender_table = task['table'];
72 sender_message = task['message']
75 Note that in lua, both sender and receiver share the same lua task.
76 So that the receiver could joint data directly on the received task without sending it back.
77 You can find a complet example (matrix multiplication case) in the file example/lua/mult_matrix.lua.
80 \subsubsection bindings_binding_lua_example_bypass Bypass XML
81 maybe you wonder if there is a way to bypass the XML files,
82 and describe your platform directly from the code, with lua bindings it's Possible !! how ?
83 We provide some additional (tricky?) functions in lua that allows you to set up your own platform without using the XML files
84 ( this can be useful for large platforms, so a simple for loop will avoid you to deal with an annoying XML File ;) )
89 simgrid.AS.new{id="AS0",mode="Full"};
94 simgrid.Host.new{id="Tremblay",power=98095000};
95 simgrid.Host.new{id="Jupiter",power=76296000};
96 simgrid.Host.new{id="Fafard",power=76296000};
97 simgrid.Host.new{id="Ginette",power=48492000};
98 simgrid.Host.new{id="Bourassa",power=48492000};
100 we use simgrid.Host.new{id=id_host,power=power_host} to instanciate our hosts.
105 simgrid.Link.new{id=i,bandwidth=252750+ i*768,latency=0.000270544+i*0.087}; -- some crazy values ;)
108 we used simgrid.Link.new{id=link_id,bandwidth=bw,latency=lat} with a simple for loop to create all links we need (much easier than XML hein ?)
112 -- simgrid.Route.new(src_id,des_id,links_nb,links_list)
113 simgrid.Route.new("Tremblay","Jupiter",1,{"1"});
114 simgrid.Route.new("Tremblay","Fafard",6,{"0","1","2","3","4","8"});
115 simgrid.Route.new("Tremblay","Ginette",3,{"3","4","5"});
116 simgrid.Route.new("Tremblay","Bourassa",7,{"0","1","3","2","4","6","7"});
118 simgrid.Route.new("Jupiter","Tremblay",1,{"1"});
119 simgrid.Route.new("Jupiter","Fafard",7,{"0","1","2","3","4","8","9"});
120 simgrid.Route.new("Jupiter","Ginette",4,{"3","4","5","9"});
121 simgrid.Route.new("Jupiter","Bourassa",8,{"0","1","2","3","4","6","7","9"});
124 for each host you have to specify which route to choose to access to the rest of hosts connected in the grid.
128 simgrid.register_platform();
130 Don't forget to register your platform, that SURF callbacks starts their work ;)
134 simgrid.Host.setFunction("Tremblay","Master",4,{"20","550000000","1000000","4"});
135 simgrid.Host.setFunction("Bourassa","Slave",1,{"0"});
136 simgrid.Host.setFunction("Jupiter","Slave",1,{"1"});
137 simgrid.Host.setFunction("Fafard","Slave",1,{"2"});
138 simgrid.Host.setFunction("Ginette","Slave",1,{"3"});
140 you don't need to use a deployment XML file, thanks to simgrid.Host.setFunction(host_id,function,args_number,args_list)
141 you can associate functions for each host with arguments if needed .
145 simgrid.register_application();
147 Yes, Here too you have to resgiter your application before running the simulation.
149 the full example is distributed in the file examples/lua/master_slave_bypass.lua
151 \subsection bindings_binding_ruby Ruby Binding
154 \subsubsection bindings_binding_ruby_simgrid Use Ruby in Simgrid
155 Since v3.4, the use of <a href="http://ruby-lang.org">ruby</a> in simgrid is available for the MSG Module.
156 you can find almost all MSG functionalities in Ruby code, that allows you to set up your environment, manage tasks between hosts and run the simulation.
158 \subsubsection bindings_binding_ruby_example Master/Slave Ruby Application
159 for each process method(master and slave in this example), you have to associate a ruby class, that should inherit from <i>MSG::Process</i> ruby class,
160 with a 'main' function that describe the behaviour of the process during the simulation.
169 class Master < MSG::Process
170 # main : that function that will be executed when running simulation
172 def main(args) # args is an array containing arguments for function master
175 MSG::info("args["+String(i)+"]="+args[i])
178 raise "Master needs 3 arguments" if size < 3
179 numberOfTask = Integer(args[0])
180 taskComputeSize = Float(args[1])
181 taskCommunicationSize = Float(args[2])
182 slaveCount = Integer(args[3])
184 # Creates and sends the tasks
185 for i in 0..numberOfTask-1
186 task = Task.new("Task_"+ i.to_s, taskComputeSize , taskCommunicationSize);
187 mailbox = "slave " + (i%slaveCount).to_s
188 MSG::info("Master Sending "+ task.name + " to " + mailbox + " with Comput Size " +
191 MSG::info("Master Done Sending " + task.name + " to " + mailbox)
194 # Sending Finalize MSG::Tasks
195 MSG::info("Master: All tasks have been dispatched. Let's tell everybody the computation is over.")
196 for i in 0..slaveCount-1
197 mailbox = "slave " + i.to_s
198 finalize_task = Task.new("finalize",0,0)
199 finalize_task.send(mailbox)
201 MSG::info("Master : Everything's Done")
207 the class MSG::Task contains methods that allows the management of the native MSG tasks.
208 in master ruby code we used :
209 - <i>MSG::Task.new(task_name,compute_size,communication_size)</i> : to instanciate a new task.
210 - <i>MSG::Task.send(mailbox)</i> : to send the task via a mailbox alias.
211 - <i>MSG::Task.name</i> : to get the task's name.
215 class Slave < MSG::Process
218 mailbox = "slave " + args[0]
219 for i in 0..args.size-1
220 MSG::debug("args["+String(i)+"]="+args[i])
224 MSG::info("Slave '"+ mailbox +"' waiting for new task");
225 task = Task.receive(mailbox)
226 if (task.name == "finalize")
230 MSG::info("Slave '" + mailbox + "' done executing task "+ task.name + ".")
232 MSG::info("I'm done, see you")
236 to receive a task, we use the method <i>MSG::Task.receive(mailbox)</i> that return a MSG:Task object (received task).
245 if (ARGV.length == 2)
246 MSG.createEnvironment(ARGV[0])
247 MSG.deployApplication(ARGV[1])
251 MSG.createEnvironment("platform.xml")
252 MSG.deployApplication("deploy.xml")
255 puts "Simulation time : " + MSG.getClock.to_s
259 - <i>MSG.createEnvironment(platform_file)</i> : set up the environment
260 - <i>MSG.deployApplication(deployment_file)</i> : load the deployment file description.
261 - <i>MSG.run</i> : run the simulation
263 \subsubsection bindings_binding_ruby_data Exchanging data
264 ruby bindings provides two ways to exchange data between ruby processes.
265 \li MSG::Task.join & MSG::Task.data <br/>
267 the MSG::Task class contains 2 methods that allows a data exchange between 2 process.
269 -<i>MSG::Task.join</i> : makes possible to join any kind of ruby data within a task.
273 myTable <<1<<-2<<45<<67<<87<<76<<89<<56<<78<<3<<-4<<99
274 # Creates and send Task With the Table inside
275 task = MSG::Task.new("quicksort_task",taskComputeSize, taskCommunicationSize);
280 -<i>MSG::Task.data</i> : to access to the data contained into the task.
283 task = MSG::Task.receive(recv_mailbox.to_s)
285 quicksort(table,0,table.size-1)
288 you can find a complet example illustrating the use of those methods in file /example/ruby/Quicksort.rb
292 another 'object-oriented' way to do it, is to make your own 'task' class that inherit from MSG::Task ,
293 and contains data you want to deal with, the only 'tricky' thing is that "the initializer" method has no effect !
295 the use of some getter/setter methods would be the simple way to manage your data :)
297 class PingPongTask < MSG::Task
298 # The initialize method has no effect
308 you can find an example of use in file example/ruby/PingPong.rb