Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Keep the button press.
[simgrid.git] / doc / bindings.doc
1 /*! \page bindings Bindings
2
3 \htmlinclude .bindings.doc.toc
4
5 \section bindings_start Available bindings
6
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.
13
14
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.
29   
30 \dontinclude lua/masterslave/master.lua
31 \subsubsection bindings_binding_lua_example_master_slave Master/Slave Example
32
33  \li Master Code
34  \until end_of_master
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. 
38
39 \dontinclude lua/masterslave/slave.lua
40 \li Slave Code
41 \until end_of_slave
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.
44
45 \dontinclude lua/masterslave/master_slave.lua
46 \li Set Environmenet and run application
47 \until simgrid.clean()
48
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.
53
54 \li Sender process
55 \verbatim 
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 ) !! "
60   …
61   simgrid.Task.send(task,alias)
62 \endverbatim
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.
65
66
67 \li Receiver processe
68 \verbatim
69   task = simgrid.Task.recv(alias);
70   sender_matrix = task['matrix'];
71   sender_table = task['table'];
72   sender_message = task['message']
73   ...
74 \endverbatim
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. 
78
79
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 ;) )
85      
86
87 \li set Routing mode
88 \verbatim
89    simgrid.AS.new{id="AS0",mode="Full"};
90 \endverbatim
91
92 \li set Hosts
93 \verbatim
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};
99 \endverbatim
100   we use simgrid.Host.new{id=id_host,power=power_host} to instanciate our hosts.
101
102 \li set Links
103 \verbatim
104   for i=0,11 do
105     simgrid.Link.new{id=i,bandwidth=252750+ i*768,latency=0.000270544+i*0.087};    --  some crazy values ;)
106   end
107 \endverbatim
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 ?)
109
110 \li set Routes
111 \verbatim
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"});
117
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"});
122    ...
123 \endverbatim
124   for each host you have to specify which route to choose to access to the rest of hosts connected in the grid.
125   
126 \li Save platform
127 \verbatim
128   simgrid.register_platform();
129 \endverbatim
130 Don't forget to register your platform, that SURF callbacks starts their work ;)
131
132 \li set application
133 \verbatim
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"});
139 \endverbatim
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 .
142
143 \li
144 \verbatim
145    simgrid.register_application();
146 \endverbatim
147 Yes, Here too you have to resgiter your application before running the simulation.
148
149 the full example is distributed in the file examples/lua/master_slave_bypass.lua
150
151 \subsection bindings_binding_ruby Ruby Binding
152
153
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.
157
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.
161 \li required stuff
162 \verbatim
163 require 'simgrid'
164 include MSG
165 \endverbatim
166
167 \li Master code
168 \verbatim
169 class Master < MSG::Process 
170   # main : that function that will be executed when running simulation
171
172   def main(args) # args is an array containing arguments for function master
173    size = args.size
174    for i in 0..size-1
175      MSG::info("args["+String(i)+"]="+args[i])
176    end
177   
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]) 
183    
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 " + 
189            task.compSize.to_s)
190      task.send(mailbox)
191      MSG::info("Master Done Sending " + task.name + " to " + mailbox)
192     end
193   
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)
200    end
201    MSG::info("Master : Everything's Done")
202   end    
203 end
204 \endverbatim
205
206
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.
212
213 \li Slave code
214 \verbatim
215 class Slave < MSG::Process
216
217   def main(args)
218     mailbox = "slave " + args[0]
219     for i in 0..args.size-1
220       MSG::debug("args["+String(i)+"]="+args[i])
221     end
222
223     while true
224        MSG::info("Slave '"+ mailbox +"' waiting for new task");
225        task = Task.receive(mailbox)
226        if (task.name == "finalize")
227                break
228        end
229        task.execute
230        MSG::info("Slave '" + mailbox + "' done executing task "+ task.name + ".")
231     end
232     MSG::info("I'm done, see you")
233   end
234 end
235 \enverbatim
236 to receive a task, we use the method <i>MSG::Task.receive(mailbox)</i> that return a MSG:Task object (received task).
237
238 \li Main chunk
239
240 \verbatim
241 require 'simgrid'
242 include MSG
243 (...)
244
245 if (ARGV.length == 2) 
246         MSG.createEnvironment(ARGV[0])
247         MSG.deployApplication(ARGV[1])
248
249 else
250
251         MSG.createEnvironment("platform.xml")
252         MSG.deployApplication("deploy.xml")
253 end
254 MSG.run
255 puts "Simulation time : " + MSG.getClock.to_s
256 MSG.exit
257 \endverbatim
258
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
262
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/>
266
267   the MSG::Task class contains 2 methods that allows a data exchange between 2 process.
268   
269   -<i>MSG::Task.join</i> : makes possible to join any kind of ruby data within a task.
270   \verbatim
271    ...
272    myTable = Array.new
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);
276    task.join(myTable);
277    ...
278    task.send(mailbox);
279    \endverbatim
280    -<i>MSG::Task.data</i> : to access to the data contained into the task.
281    \verbatim
282    ...
283    task = MSG::Task.receive(recv_mailbox.to_s)
284    table = task.data
285    quicksort(table,0,table.size-1)
286    ...
287    \endverbatim
288 you can find a complet example illustrating the use of those methods  in file /example/ruby/Quicksort.rb
289
290 \li inheritence 
291  
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 ! 
294  
295  the use of some getter/setter methods would be the simple way to manage your data :)
296  \verbatim
297 class PingPongTask < MSG::Task
298   # The initialize method has no effect 
299   @time 
300   def setTime(t)
301     @time = t
302   end
303   def getTime()
304     return @time
305   end
306 end
307  \endverbatim
308  you can find an example of use in file example/ruby/PingPong.rb
309
310  */