Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > VReo > VReo__Prod_Cons__LangDev
changeset 0:5b757d5a7044
Initial add -- fully working
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Wed, 12 Jun 2013 15:13:34 -0700 |
| parents | |
| children | a4796deb8c8b |
| files | .hgeol .hgignore Design_Notes.txt VReo__Test_App/Circuit.c VReo__Test_App/Circuit.h VReo__Test_App/Producer_and_Consumer.c VReo__Test_App/SeedVP.c VReo__Test_App/VReo__Test_App.h __brch__ML_dev main.c |
| diffstat | 10 files changed, 748 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgeol Wed Jun 12 15:13:34 2013 -0700 1.3 @@ -0,0 +1,14 @@ 1.4 + 1.5 +[patterns] 1.6 +**.py = native 1.7 +**.txt = native 1.8 +**.c = native 1.9 +**.h = native 1.10 +**.cpp = native 1.11 +**.java = native 1.12 +**.class = bin 1.13 +**.jar = bin 1.14 +**.sh = native 1.15 +**.pl = native 1.16 +**.jpg = bin 1.17 +**.gif = bin
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/.hgignore Wed Jun 12 15:13:34 2013 -0700 2.3 @@ -0,0 +1,12 @@ 2.4 +nbproject 2.5 +Makefile 2.6 +build 2.7 +dist 2.8 +src/Default 2.9 +src/.settings 2.10 +src/.cproject 2.11 +src/.project 2.12 +.dep.inc 2.13 +glob:.cproject 2.14 +glob:.project 2.15 +glob:Debug
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/Design_Notes.txt Wed Jun 12 15:13:34 2013 -0700 3.3 @@ -0,0 +1,29 @@ 3.4 + 3.5 +This test app is for VReo development.. first version replicates a program 3.6 +from the paper. It has two producers and one consumer. The circuit causes 3.7 +the producers to take turns providing the next input that the consumer takes. 3.8 + 3.9 +The circuit is in the paper.. 3.10 + 3.11 +The way the code works, the circuit is supplied separately. A function is 3.12 +generated by a tool, which creates the circuit data structs. Those structs 3.13 +contain pointers to the functions that check transitions and then perform 3.14 +transitions. 3.15 + 3.16 +So, the seed first starts up VReo, then it calls the create circuit Fn, 3.17 +which returns a pointer to the circuit, then it calls create_VP three 3.18 +times. The first, it hands it the pointer to the producer Fn, along with 3.19 +a pointer to the circuit and an integer that indicates that it connects to 3.20 +port 1 of the circuit. Second, it creates another producer, but connected 3.21 +to port 2, then it creates a consumer connected to port 3. 3.22 + 3.23 +Then, it waits for the computation to end. 3.24 + 3.25 +A producer puts out 5 items, doing a print for each. The consumer consumes 3.26 +10 items, doing a print for each. 3.27 + 3.28 +Then each of them call "end_VP". 3.29 + 3.30 +That ends the computation, and the seed comes back, and calls "end_seed_VP" 3.31 + 3.32 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/VReo__Test_App/Circuit.c Wed Jun 12 15:13:34 2013 -0700 4.3 @@ -0,0 +1,380 @@ 4.4 +/* 4.5 + * Copyright 2009 OpenSourceResearchInstitute.org 4.6 + * Licensed under GNU General Public License version 2 4.7 + * 4.8 + * Author: seanhalle@yahoo.com 4.9 + * 4.10 + */ 4.11 + 4.12 + 4.13 +#include <math.h> 4.14 +#include <string.h> 4.15 +#include "VReo__Test_App.h" 4.16 + 4.17 +#include "Circuit.h" 4.18 + 4.19 +/*Create Circuit for Application 4.20 + *This is called by the seedVP to create the circuit structs, 4.21 + * which include port structs and island structs 4.22 + * 4.23 + *This circuit has two islands. 4.24 + *First island has a port A written by VP A, a port B written by VP B, and a 4.25 + * port C that is a FIFO it writes. 4.26 + * 4.27 + *Second island has a FIFO port Cp that it reads, and a VP port D that it 4.28 + * writes 4.29 + * 4.30 + * 4.31 + *Circuit code is written separately from the application 4.32 + *It creates the island structures and the port structures 4.33 + *Returns an array of pointer to the ports on the boundary 4.34 + */ 4.35 +VReoCircuit * 4.36 +create_circuit__Test_App( SlaveVP *animVP ) 4.37 + { VReoCircuit *circuit; 4.38 + VReoPort *port, *ports, **boundaryPorts; 4.39 + VReoIsland *islands, *island; 4.40 + 4.41 + //create uninitialized port structs, by allocating space in array 4.42 + ports = PR_WL__malloc( NUM_PORTS * sizeof(VReoPort) ); 4.43 + 4.44 + //create uninitialized islands, by allocating space in array 4.45 + islands = PR_WL__malloc( NUM_ISLANDS * sizeof(VReoIsland) ); 4.46 + 4.47 + //======================= Set up Islands ======================== 4.48 + //== 4.49 + //set up first island 4.50 + island = &( islands[CKT_I1] ); //easier to work with a pointer 4.51 + 4.52 + //fill in pointers to checker functions 4.53 + island->numCheckerFns = 2; 4.54 + island->checkerFns = 4.55 + PR_WL__malloc( island->numCheckerFns * sizeof(VReoCheckerFn) ); 4.56 + island->checkerFns[0] = &Checker_1__I1; 4.57 + island->checkerFns[1] = &Checker_2__I1; 4.58 + 4.59 + //fill in pointers to doer functions 4.60 + island->doerFns = 4.61 + PR_WL__malloc( island->numCheckerFns * sizeof(VReoDoerFn) ); 4.62 + island->doerFns[0] = &Doer_1__I1; 4.63 + island->doerFns[1] = &Doer_2__I1; 4.64 + 4.65 + //create space for pointers to ports 4.66 + island->numPorts = 3; 4.67 + island->ports = PR_WL__malloc( island->numPorts * sizeof(VReoPort *) ); 4.68 + 4.69 + //connect ports to island 4.70 + island->ports[I1_PORT_Ar] = &(ports[CKT_PORT_A]); 4.71 + island->ports[I1_PORT_Br] = &(ports[CKT_PORT_B]); 4.72 + island->ports[I1_PORT_Cw] = &(ports[CKT_PORT_C]); 4.73 + 4.74 + //== 4.75 + //set up second island 4.76 + island = &( islands[CKT_I2] ); //easier to work with a pointer 4.77 + 4.78 + //fill in pointers to checker functions 4.79 + island->numCheckerFns = 1; 4.80 + island->checkerFns = 4.81 + PR_WL__malloc( island->numCheckerFns * sizeof(VReoCheckerFn) ); 4.82 + island->checkerFns[0] = &Checker_1__I2; 4.83 + 4.84 + //fill in pointers to doer functions 4.85 + island->doerFns = 4.86 + PR_WL__malloc( island->numCheckerFns * sizeof(VReoDoerFn) ); 4.87 + island->doerFns[0] = &Doer_1__I2; 4.88 + 4.89 + //create space for pointers to ports 4.90 + island->numPorts = 2; 4.91 + island->ports = PR_WL__malloc( island->numPorts * sizeof(VReoPort *) ); 4.92 + 4.93 + //connect ports to island 4.94 + island->ports[I2_PORT_Cr] = &(ports[CKT_PORT_C]); 4.95 + island->ports[I2_PORT_Dw] = &(ports[CKT_PORT_D]); 4.96 + 4.97 + //========================= Connect ports ========================= 4.98 + //== 4.99 + //Connect port 1 to islands and/or VPs 4.100 + port = &(ports[CKT_PORT_A]); 4.101 + port->reader = &(islands[CKT_I1]); 4.102 + 4.103 + //initialize port 4.104 + port->buffer = NULL; 4.105 + port->portIsFull = FALSE; 4.106 + port->waitingReaderVP = NULL; 4.107 + port->waitingWriterVP = NULL; 4.108 + 4.109 + 4.110 + //Connect port 2 to islands and/or VPs 4.111 + port = &(ports[CKT_PORT_B]); 4.112 + port->reader = &(islands[CKT_I1]); 4.113 + 4.114 + //initialize port 4.115 + port->buffer = NULL; 4.116 + port->portIsFull = FALSE; 4.117 + port->waitingReaderVP = NULL; 4.118 + port->waitingWriterVP = NULL; 4.119 + 4.120 + 4.121 + //Connect port 3 to islands and/or VPs 4.122 + port = &(ports[CKT_PORT_C]); 4.123 + port->writer = &(islands[CKT_I1]); 4.124 + port->reader = &(islands[CKT_I2]); 4.125 + 4.126 + //initialize port 4.127 + port->buffer = NULL; 4.128 + port->portIsFull = FALSE; 4.129 + port->waitingReaderVP = NULL; 4.130 + port->waitingWriterVP = NULL; 4.131 + 4.132 + 4.133 + //Connect port 4 to islands and/or VPs 4.134 + port = &(ports[CKT_PORT_D]); 4.135 + port->writer = &(islands[CKT_I2]); 4.136 + 4.137 + //initialize port 4.138 + port->buffer = NULL; 4.139 + port->portIsFull = FALSE; 4.140 + port->waitingReaderVP = NULL; 4.141 + port->waitingWriterVP = NULL; 4.142 + 4.143 + 4.144 + 4.145 + 4.146 + //======================= Set up Circuit ======================== 4.147 + //== 4.148 + circuit = (VReoCircuit *)PR_WL__malloc( sizeof(VReoCircuit) ); 4.149 + 4.150 + circuit->numIslands = NUM_ISLANDS; 4.151 + circuit->islands = islands; 4.152 + 4.153 + circuit->numPorts = NUM_PORTS; 4.154 + circuit->ports = ports; 4.155 + 4.156 + //populate the array of ports that are on the boundary of the 4.157 + //Note: it is up to the "user" of the circuit to know the order of the 4.158 + // ports, and whether a particular one is input vs output 4.159 + boundaryPorts = PR_WL__malloc( NUM_BOUNDARY_PORTS * sizeof(VReoPort*) ); 4.160 + boundaryPorts[0] = &(ports[CKT_PORT_A]); 4.161 + boundaryPorts[1] = &(ports[CKT_PORT_B]); 4.162 + boundaryPorts[2] = &(ports[CKT_PORT_D]); 4.163 + 4.164 + circuit->boundaryPorts = boundaryPorts; 4.165 + 4.166 + circuit->VPs = NULL; //must initialize, 'cause used to detect end of list 4.167 + 4.168 + return(circuit); 4.169 + } 4.170 + 4.171 + 4.172 + 4.173 +/*The Connections between the virtual processors and the circuit 4.174 + * are defined as part of the application development 4.175 + *A connection correlates a port accessed inside application code 4.176 + * to a port on the boundary of a circuit. 4.177 + *The connection is represented by a pointer to a particular port 4.178 + * being placed into a particular index in a virtual processor's 4.179 + * array of ports. 4.180 + *This function both creates the connection-arrays for a given 4.181 + * VP instance, then it makes that VP instance, passing it the 4.182 + * connection-array. 4.183 + */ 4.184 +void 4.185 +create_VPs_and_connect__Test_App( VReoCircuit *circuit, SlaveVP *animVP ) 4.186 + { VReoPort **boundaryPorts; 4.187 + 4.188 + TestAppProducerParams *prodParams; 4.189 + TestAppConsumerParams *consParams; 4.190 + 4.191 + boundaryPorts = circuit->boundaryPorts; 4.192 + 4.193 + //====================== Create VPs ====================== 4.194 + //== 4.195 + //when create a VP, pass it an array of pointers to ports. 4.196 + //VP keeps the array 4.197 + //VP function has hard-coded into it which port idx it puts to or gets 4.198 + // from 4.199 + VReoPort **portsForVP; //array of pointers 4.200 + SlaveVP **VPs; //array of pointers 4.201 + 4.202 + VPs = PR_WL__malloc( NUM_VPs * sizeof(SlaveVP *) ); 4.203 + 4.204 + //array of pointers to ports, that is given to VP 4.205 + portsForVP = PR_WL__malloc( 1 * sizeof(VReoPort *) ); 4.206 + //connect VP's 0th input port to the circuit's 0th boundary port 4.207 + portsForVP[0] = boundaryPorts[0]; 4.208 + prodParams = PR_WL__malloc( sizeof(TestAppProducerParams) ); 4.209 + prodParams->inPorts = NULL; 4.210 + prodParams->outPorts = portsForVP; 4.211 + VPs[CKT_VP1] = VReo__create_VP( &producer_Fn, prodParams, circuit, animVP ); 4.212 + boundaryPorts[0]->writer = VPs[CKT_VP1]; 4.213 +// PRServ__pass_mem_ownership_of_to( portsForVP, VPs[0] ); 4.214 + 4.215 + portsForVP = PR_WL__malloc( 1 * sizeof(VReoPort *) ); 4.216 + //connect VP's 0th input port to the circuit's 1-idx boundary port 4.217 + portsForVP[0] = boundaryPorts[1]; 4.218 + prodParams = PR_WL__malloc( sizeof(TestAppProducerParams) ); 4.219 + prodParams->inPorts = NULL; 4.220 + prodParams->outPorts = portsForVP; 4.221 + VPs[CKT_VP2] = VReo__create_VP( &producer_Fn, prodParams, circuit, animVP ); 4.222 + boundaryPorts[1]->writer = VPs[CKT_VP2]; 4.223 +// PRServ__pass_mem_ownership_of_to( portsForVP, VPs[1] ); 4.224 + 4.225 + portsForVP = PR_WL__malloc( 1 * sizeof(VReoPort *) ); 4.226 + //connect VP's 0th output port to the circuit's 2-idx boundary port 4.227 + portsForVP[0] = boundaryPorts[2]; //connects circuit boundary port to VP port 4.228 + consParams = PR_WL__malloc( sizeof(TestAppConsumerParams) ); 4.229 + consParams->inPorts = portsForVP; 4.230 + consParams->outPorts = NULL; 4.231 + VPs[CKT_VP3] = VReo__create_VP( &consumer_Fn, consParams, circuit, animVP ); 4.232 + boundaryPorts[2]->reader = VPs[CKT_VP3]; 4.233 +// PRServ__pass_mem_ownership_of_to( portsForVP, VPs[2] ); 4.234 + 4.235 + //Now that all the connections in circuit are complete, can start it 4.236 + VReo__start_circuit( circuit, animVP ); 4.237 + } 4.238 + 4.239 + 4.240 +/*A Checker function is one-to-one with a transition of the state machine. 4.241 + * It takes as input an Island data-struct, and proceeds to check the states 4.242 + * of each port that it cares about. It accesses the ports through the 4.243 + * island struct. 4.244 + */ 4.245 + 4.246 +/*Island 1 4.247 + *Checkers: 4.248 + * 1) A offering and C empty 4.249 + * 2) B offering and C empty 4.250 + *Note: C is a FIFO port, so don't need to check for VP waiting to accept. 4.251 + */ 4.252 +bool32 4.253 +Checker_1__I1( VReoIsland *island ) 4.254 + { VReoPort *portA, *portC; 4.255 + bool32 satisfied; 4.256 + 4.257 + portA = (island->ports)[I1_PORT_Ar]; 4.258 + portC = (island->ports)[I1_PORT_Cw]; 4.259 + satisfied = portA->portIsFull && ! portC->portIsFull; 4.260 + return satisfied; 4.261 + } 4.262 +bool32 4.263 +Checker_2__I1( VReoIsland *island ) 4.264 + { VReoPort *portB, *portC; 4.265 + bool32 satisfied; 4.266 + 4.267 + portB = (island->ports)[I1_PORT_Br]; 4.268 + portC = (island->ports)[I1_PORT_Cw]; 4.269 + satisfied = portB->portIsFull && ! portC->portIsFull; 4.270 + return satisfied; 4.271 + } 4.272 + 4.273 +/*Island 1 4.274 + *Doers: 4.275 + * 1) take from A, put into C, resume A 4.276 + * 2) take from B, put into C, resume B 4.277 + *Note: C is a FIFO port, so no VP on C to resume 4.278 + *Hard-code that C is a FIFO port because generated this from circuit 4.279 + */ 4.280 +void 4.281 +Doer_1__I1( VReoIsland *island ) 4.282 + { VReoPort *portA, *portC; 4.283 + VReoIsland *islandOnOtherSide; 4.284 + void *temp; 4.285 + 4.286 + portA = (island->ports)[I1_PORT_Ar]; 4.287 + portC = (island->ports)[I1_PORT_Cw]; 4.288 + temp = portA->buffer; 4.289 + portA->portIsFull = FALSE; 4.290 + portC->buffer = temp; 4.291 + portC->portIsFull = TRUE; 4.292 + 4.293 + //Just wrote into C, which has an island on the other side, so check it 4.294 + //Note, may have been that island that caused THIS check.. but check it 4.295 + // anyway, this second go will not satisfy any checkers.. later do an 4.296 + // optimization that remembers what triggered, to avoid this redundancy 4.297 + islandOnOtherSide = (VReoIsland *)portC->reader; 4.298 + VReo__check_an_island( islandOnOtherSide, islandOnOtherSide->numCheckerFns, 4.299 + islandOnOtherSide->checkerFns, islandOnOtherSide->doerFns ); 4.300 + 4.301 + //A was made full by the request handler, which wrote buffer and flags 4.302 + //A was full, so guaranteed to have a VP waiting to resume 4.303 + PR_PI__make_slave_ready_for_lang( portA->waitingWriterVP, VReo_MAGIC_NUMBER); 4.304 + portA->waitingWriterVP = NULL; 4.305 + } 4.306 +void 4.307 +Doer_2__I1( VReoIsland *island ) 4.308 + { VReoPort *portB, *portC; 4.309 + VReoIsland *islandOnOtherSide; 4.310 + void *temp; 4.311 + 4.312 + portB = (island->ports)[I1_PORT_Br]; 4.313 + portC = (island->ports)[I1_PORT_Cw]; 4.314 + temp = portB->buffer; 4.315 + portB->portIsFull = FALSE; 4.316 + portC->buffer = temp; 4.317 + portC->portIsFull = TRUE; 4.318 + 4.319 + islandOnOtherSide = (VReoIsland *)portC->reader; 4.320 + VReo__check_an_island( islandOnOtherSide, islandOnOtherSide->numCheckerFns, 4.321 + islandOnOtherSide->checkerFns, islandOnOtherSide->doerFns ); 4.322 + 4.323 + //was full, so guaranteed to have a VP waiting to resume 4.324 + PR_PI__make_slave_ready_for_lang( portB->waitingWriterVP, VReo_MAGIC_NUMBER ); 4.325 + portB->waitingWriterVP = NULL; 4.326 + } 4.327 + 4.328 +/*Island 2 4.329 + *Checkers: 4.330 + * 1) Cp full and D has a waiting VP 4.331 + */ 4.332 +bool32 4.333 +Checker_1__I2( VReoIsland *island ) 4.334 + { VReoPort *portC, *portD; 4.335 + bool32 satisfied; 4.336 + 4.337 + portC = (island->ports)[I2_PORT_Cr]; 4.338 + portD = (island->ports)[I2_PORT_Dw]; 4.339 + satisfied = portC->portIsFull && portD->waitingReaderVP; 4.340 + return satisfied; 4.341 + } 4.342 + 4.343 +/*Island 2 4.344 + *Doers: 4.345 + * 1) take from Cp, put into D, resume VP waiting on D, recheck I1 4.346 + */ 4.347 +void 4.348 +Doer_1__I2( VReoIsland *island ) 4.349 + { VReoPort *portC, *portD; 4.350 + VReoIsland *islandOnOtherSide; 4.351 + void *temp; 4.352 + 4.353 + portC = (island->ports)[I2_PORT_Cr]; 4.354 + portD = (island->ports)[I2_PORT_Dw]; 4.355 + temp = portC->buffer; 4.356 + portC->portIsFull = FALSE; 4.357 + 4.358 + 4.359 + portD->buffer = temp; 4.360 + portD->portIsFull = TRUE; 4.361 + 4.362 + //D guaranteed to be empty, with VP waiting to take, so always have a VP 4.363 + // that takes what is put into D and resumes with that value. So, can 4.364 + // do an optimization where don't write buffer, nor set full flag, if 4.365 + // want. 4.366 + 4.367 + //Here, take value out of port, and resume VP with it. 4.368 + portD->waitingReaderVP->dataRetFromReq = portD->buffer; 4.369 + portD->portIsFull = FALSE; 4.370 + PR_PI__make_slave_ready_for_lang( portD->waitingReaderVP, VReo_MAGIC_NUMBER ); 4.371 + portD->waitingReaderVP = NULL; 4.372 + 4.373 + //Just emptied C, which has an island on the other side, so check it 4.374 + //Note, may have been that island that caused THIS check.. but check it 4.375 + // anyway, this second go may not satisfy any checkers.. later do an 4.376 + // optimization that remembers what triggered, to avoid redundancy 4.377 + islandOnOtherSide = (VReoIsland *)portC->writer; 4.378 + VReo__check_an_island( islandOnOtherSide, islandOnOtherSide->numCheckerFns, 4.379 + islandOnOtherSide->checkerFns, islandOnOtherSide->doerFns ); 4.380 + } 4.381 + 4.382 + 4.383 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/VReo__Test_App/Circuit.h Wed Jun 12 15:13:34 2013 -0700 5.3 @@ -0,0 +1,67 @@ 5.4 +/* 5.5 + * Copyright 2009 OpenSourceResearchInstitute.org 5.6 + * Licensed under GNU General Public License version 2 5.7 + * 5.8 + * Author: seanhalle@yahoo.com 5.9 + * 5.10 + */ 5.11 + 5.12 +#ifndef _Circuit_App1_H 5.13 +#define _Circuit_App1_H 5.14 + 5.15 +#include "PR_impl/PR.h" 5.16 +#include "VReo_impl/VReo.h" 5.17 + 5.18 +//========================================================================== 5.19 +#define NUM_ISLANDS 2 5.20 +#define NUM_PORTS 4 5.21 +#define NUM_BOUNDARY_PORTS 3 5.22 +#define NUM_VPs 3 5.23 + 5.24 +//Using defined symbols like this modularizes the process of generating the 5.25 +// code 5.26 +#define CKT_I1 0 5.27 +#define CKT_I2 1 5.28 + 5.29 +#define CKT_PORT_A 0 5.30 +#define CKT_PORT_B 1 5.31 +#define CKT_PORT_C 2 5.32 +#define CKT_PORT_D 4 5.33 + 5.34 +#define I1_PORT_Ar 0 5.35 +#define I1_PORT_Br 1 5.36 +#define I1_PORT_Cw 2 5.37 + 5.38 +#define I2_PORT_Cr 0 5.39 +#define I2_PORT_Dw 1 5.40 + 5.41 +#define CKT_VP1 0 5.42 +#define CKT_VP2 1 5.43 +#define CKT_VP3 2 5.44 + 5.45 +//called by seedVP to create the circuit structs, including ports and islands 5.46 +VReoCircuit * 5.47 +create_circuit__Test_App( SlaveVP *animVP ); 5.48 + 5.49 +void 5.50 +create_VPs_and_connect__Test_App( VReoCircuit *circuit, SlaveVP *animVP ); 5.51 + 5.52 + 5.53 +bool32 5.54 +Checker_1__I1( VReoIsland *island ); 5.55 +bool32 5.56 +Checker_2__I1( VReoIsland *island ); 5.57 +void 5.58 +Doer_1__I1( VReoIsland *island ); 5.59 +void 5.60 +Doer_2__I1( VReoIsland *island ); 5.61 + 5.62 + 5.63 +bool32 5.64 +Checker_1__I2( VReoIsland *island ); 5.65 +void 5.66 +Doer_1__I2( VReoIsland *island ); 5.67 + 5.68 + 5.69 +#endif /* _Circuit_App1_H */ 5.70 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/VReo__Test_App/Producer_and_Consumer.c Wed Jun 12 15:13:34 2013 -0700 6.3 @@ -0,0 +1,64 @@ 6.4 +/* 6.5 + * Copyright 2009 OpenSourceResearchInstitute.org 6.6 + * Licensed under GNU General Public License version 2 6.7 + * 6.8 + * Author: seanhalle@yahoo.com 6.9 + * 6.10 + */ 6.11 + 6.12 + 6.13 +#include <math.h> 6.14 +#include <string.h> 6.15 +#include "VReo__Test_App.h" 6.16 + 6.17 +/*The input to a VP's birth function is a struct that holds two arrays of 6.18 + * pointers to ports -- one for input ports, one for output ports 6.19 + */ 6.20 +void producer_Fn( void *_birthParams, SlaveVP *animVP ) 6.21 + { TestAppProducerParams *birthParams = (TestAppProducerParams *)_birthParams; 6.22 + //Tell the Reo tool that generates circuit about the ports of this VP 6.23 + //#Reo numInPorts 0 | numOutports 1 6.24 + VReoPort **outPorts = birthParams->outPorts; 6.25 + VReoPort *port; 6.26 + TestAppProdConsMsg *msg; 6.27 + int32 i; 6.28 + 6.29 + DEBUG__printf1(dbgAppFlow, "Producer on core: %d", animVP->coreAnimatedBy); 6.30 + 6.31 + port = outPorts[0]; 6.32 + 6.33 + //A producer puts out 5 items, doing a print for each. 6.34 + for( i=0; i<5; i++) 6.35 + { 6.36 + msg = PR__malloc( sizeof(TestAppProdConsMsg) ); 6.37 + msg->producerID = animVP->slaveNum; 6.38 + msg->producedCnt = i + 1; 6.39 + DEBUG__printf2(dbgAppFlow,"Producer %d, put in %d", msg->producerID, msg->producedCnt); 6.40 + VReo__put_into_port( msg, port, animVP ); 6.41 + } 6.42 + VReo__end_VP( animVP ); 6.43 + } 6.44 + 6.45 + 6.46 +void consumer_Fn( void *_args, SlaveVP *animVP ) 6.47 + { TestAppConsumerParams *params = (TestAppConsumerParams *)_args; 6.48 + //Tell the Reo tool that generates circuit about the ports of this VP 6.49 + //#Reo numInPorts 1 | numOutports 0 6.50 + VReoPort **inPorts = params->inPorts; 6.51 + VReoPort *port; 6.52 + int32 i, got; 6.53 + TestAppProdConsMsg *msg; 6.54 + 6.55 + DEBUG__printf1(dbgAppFlow, "Consumer on core: %d", animVP->coreAnimatedBy); 6.56 + 6.57 + port = inPorts[0]; 6.58 + 6.59 + //A producer puts out 5 items, doing a print for each. 6.60 + for( i=0; i<10; i++) 6.61 + { 6.62 + msg = (TestAppProdConsMsg *) VReo__get_from_port( port, animVP ); 6.63 + DEBUG__printf2(dbgAppFlow,"Consumer got %d from %d", msg->producedCnt, msg->producerID ); 6.64 + } 6.65 + VReo__end_VP( animVP ); 6.66 + } 6.67 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/VReo__Test_App/SeedVP.c Wed Jun 12 15:13:34 2013 -0700 7.3 @@ -0,0 +1,66 @@ 7.4 +/* 7.5 + * Copyright 2009 OpenSourceResearchInstitute.org 7.6 + * Licensed under GNU General Public License version 2 7.7 + * 7.8 + * Author: seanhalle@yahoo.com 7.9 + * 7.10 + */ 7.11 + 7.12 + 7.13 +#include <math.h> 7.14 +#include <string.h> 7.15 +#include "VReo__Test_App.h" 7.16 + 7.17 +#define NO_INPUT NULL 7.18 + 7.19 +/*The _params was passed into the create_process call inside main. 7.20 + * 7.21 + * the seed first starts up VReo, then it calls the create circuit Fn, 7.22 +which returns a pointer to the circuit, then it calls create_VP three 7.23 +times. The first, it hands it the pointer to the producer Fn, along with 7.24 +a pointer to the circuit and an integer that indicates that it connects to 7.25 +port 1 of the circuit. Second, it creates another producer, but connected 7.26 +to port 2, then it creates a consumer connected to port 3. 7.27 + 7.28 +Then, it waits for the computation to end. 7.29 + 7.30 +A producer puts out 5 items, doing a print for each. The consumer consumes 7.31 +10 items, doing a print for each. 7.32 + 7.33 +Then each of them call "end_VP". 7.34 + 7.35 +That ends the computation, and the seed comes back, and calls "end_seed_VP" 7.36 + 7.37 + */ 7.38 +void test_app_seed_Fn( void *_params, SlaveVP *seedVP ) 7.39 + { 7.40 + //int32 *results = (int32 *)_params; //_params passed to create_process call 7.41 + VReoCircuit *circuit; 7.42 + 7.43 + DEBUG__printf( dbgAppFlow, "start test_app"); 7.44 + 7.45 + //first thing to do is start the langlets going to use in this 7.46 + // proglet (AKA process). 7.47 + VReo__start( seedVP ); 7.48 + 7.49 + //Invoke the create circuit command, which returns a pointer to circuit 7.50 + //This creates the VPs, which starts them running. 7.51 + circuit = (VReoCircuit *)create_circuit__Test_App( seedVP ); 7.52 + create_VPs_and_connect__Test_App( circuit, seedVP ); 7.53 + 7.54 + //Wait for work to end -- means the VPs have to end themselves once 7.55 + // they've completed their work. 7.56 + //Alternatively, could connect a port to the process that receives a 7.57 + // communication that tells the process when to end the VPs and shutdown. 7.58 + VReo__wait_for_all_VReo_created_work_to_end( seedVP ); 7.59 + 7.60 + DEBUG__printf(TRUE, "work done"); 7.61 + 7.62 + VReo__shutdown( seedVP ); //Shuts down VReo within the process 7.63 + 7.64 + //Tells PR to end the process, which it will do even 7.65 + // if work is active, or suspended work entities are still live, or the 7.66 + // process has input ports that could trigger future work. 7.67 + PR__end_process_from_inside( seedVP ); 7.68 + } 7.69 +
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/VReo__Test_App/VReo__Test_App.h Wed Jun 12 15:13:34 2013 -0700 8.3 @@ -0,0 +1,59 @@ 8.4 +/* 8.5 + * Copyright Oct 24, 2009 OpenSourceResearchInstitute.org 8.6 + * Licensed under GNU General Public License version 2 8.7 + */ 8.8 + 8.9 +#ifndef _VReo_TEST_APP_H_ 8.10 +#define _VReo_TEST_APP_H_ 8.11 + 8.12 +#include <stdio.h> 8.13 + 8.14 +#include "VReo_impl/VReo.h" 8.15 +#include "Circuit.h" 8.16 + 8.17 + 8.18 +//=============================== Defines ============================== 8.19 + 8.20 +//============================== Structures ============================== 8.21 + 8.22 +//NOTE: this is a birth function param. The first field of any structure 8.23 +// that is passed as the argument to a birth function must be a pointer to 8.24 +// the Reo circuit 8.25 +typedef struct 8.26 + { //The first field must be pointer to a circuit (because is param to birth Fn) 8.27 + VReoCircuit *circuit; //First field must ALWAYS be a pointer to a circuit 8.28 + 8.29 + VReoPort **inPorts; //array of pointers into circuit's array of ports 8.30 + VReoPort **outPorts; //array of pointers into circuit's array of ports 8.31 + } 8.32 +TestAppProducerParams; 8.33 + 8.34 +typedef struct 8.35 + { //The first field must be pointer to a circuit (because is param to birth Fn) 8.36 + VReoCircuit *circuit; //First field must ALWAYS be a pointer to a circuit 8.37 + 8.38 + VReoPort **inPorts; //array of pointers into circuit's array of ports 8.39 + VReoPort **outPorts; //array of pointers into circuit's array of ports 8.40 + } 8.41 +TestAppConsumerParams; 8.42 + 8.43 +typedef struct 8.44 + { 8.45 + int32 producerID; 8.46 + int32 producedCnt; 8.47 + } 8.48 +TestAppProdConsMsg; 8.49 + 8.50 +//============================= Processor Functions ========================= 8.51 +void test_app_seed_Fn( void *data, SlaveVP *animatingVP ); //seed VP function 8.52 +void producer_Fn( void *data, SlaveVP *animatingVP ); 8.53 +void consumer_Fn( void *data, SlaveVP *animatingVP ); 8.54 + 8.55 + 8.56 +//================================ Entry Point ============================== 8.57 +void 8.58 +VReo__Test_App( ); 8.59 + 8.60 +//================================ Global Vars ============================== 8.61 + 8.62 +#endif /*_SSR_MATRIX_MULT_H_*/
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/__brch__ML_dev Wed Jun 12 15:13:34 2013 -0700 9.3 @@ -0,0 +1,1 @@ 9.4 +Applications normally have only the default branch -- they shouldn't be affected by any choices in VMS or language..
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/main.c Wed Jun 12 15:13:34 2013 -0700 10.3 @@ -0,0 +1,56 @@ 10.4 +/* 10.5 + * Copyright 2012 OpenSourceResearchInstitute.org 10.6 + * Licensed under GNU General Public License version 2 10.7 + * 10.8 + * author seanhalle@yahoo.com 10.9 + */ 10.10 + 10.11 +#include <malloc.h> 10.12 +#include <stdlib.h> 10.13 + 10.14 +#include "VReo__Test_App/VReo__Test_App.h" 10.15 + 10.16 +#define NO_INPUT_OR_OUTPUT NULL 10.17 + 10.18 +/*This demonstrates the use of the proto-runtime system. It allows multiple 10.19 + * languages to be mixed within a single sub-program. It also allows multiple 10.20 + * sub-programs to be started, where each uses its own set of languages. The 10.21 + * running sub-programs can then communicate with each other. 10.22 + * 10.23 + */ 10.24 +int main( int argc, char **argv ) 10.25 + { PRProcess *testProcess1, *testProcess2; 10.26 + 10.27 + DEBUG__printf2(TRUE, "arguments: %s | %s", argv[0], argv[1] ); 10.28 + 10.29 + //A proto-runtime based language sits on top of the proto-runtime. So, 10.30 + // first start the proto-runtime system, then create processes (which 10.31 + // start languages inside themselves) 10.32 + PR__start(); 10.33 + 10.34 + //This info shows up in the header of output files holding measurements 10.35 + //These calls MUST be made after PR__start and before creating a process 10.36 + PR__set_app_info("Test for developing VReo"); 10.37 + PR__set_input_info("no input"); 10.38 + 10.39 + 10.40 + //Now that PR is started, create processes. 10.41 + //Each process creates a seedVP and starts it running -- that then starts 10.42 + // the languages used inside the process.. 10.43 + //To get results from a process, it gets complicated.. simple soln is 10.44 + // just use PR's malloc and free, in the main thread, between PR__start 10.45 + // and PR__shutdown 10.46 + //The call returns a process struct 10.47 + //int32 *result = PR__malloc( 2 * sizeof(int32) ); 10.48 + testProcess1 = PR__create_process( &test_app_seed_Fn, NO_INPUT_OR_OUTPUT ); 10.49 + 10.50 + PR__wait_for_process_to_end( testProcess1 ); 10.51 + printf("done \n\n" ); 10.52 + 10.53 + //PR__free(result); 10.54 + 10.55 + PR__wait_for_all_activity_to_end(); //equivalent of detecting shutdown 10.56 + PR__shutdown(); 10.57 + 10.58 + exit(0); //cleans up 10.59 + }
