Date: Thu, 28 Mar 2024 03:33:05 -0500 (CDT) Message-ID: <1463043519.914.1711614785697@wiki-n2.rice.edu> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_913_172742201.1711614785695" ------=_Part_913_172742201.1711614785695 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
First, we need to define the CnC graph:
// Decl= arations // The tag values are the odd numbers in the range [3..n] <string oddNums>; // The prime numbers as identified by the compute step [string->int primes]; // Step execution // The compute step may produce a prime number (in the form of a tag instan= ce) (compute) -> [primes]; // Step prescription // For each oddNums instance, there is <oddNums> :: (python compute); // Input from the environment: initialize all tags env -> <oddNums>; // Output to the environment is the collection of the prime numbers [primes] -> env;
The CnC graph states that oddNums
is a Tag Collection with =
strings as the tags.
Currently, strings are the only supported tag types in CnC-Python.
Next, we define the Item Collection primes
which has string=
s as tags and integer as its values. These types are defined in the format =
tagType->itemType
before the name of the Item Collection.=
p>
We define the implementation language of the Step in the Step prescripti=
on as in (python compute)
. In CnC-Python, python is the only a=
llowable value. In future releases we plan to expan this value to include o=
ther languages such as C, C++, Fortran, Matlab, etc.
env
is a special keyword representing the environment and i=
n this example we define the environment will put string tags into the primes<=
/code> Item Collection.
After defining the CnC graph, we need to run this file using the CnC-Pyt=
hon translator using the following command:cnc_t FindPrimes.cnc=
code>
Running the command will generate the following directories: hj-cn=
c-api
, sidl
, java-client
, py-lib,
user-code
, and hj-main
. In short, these are =
what the directories represent:
Directory Name |
Function |
---|---|
|
Wrapper classes for the HJ-CnC runtime used b= y Babel while generating SIDL server/client code |
|
SIDL files used by the program. This includes= the SIDL file for the runtime wrapper classes as well as the Step and Item= Collections for the current program |
|
The java client generated from the SIDL files= used by the HJ program to call into the python implementation |
|
The generated python files that are invoked f= rom the HJ program |
|
This is the only directory the user should ne= ed to edit. It will contain template files for the python Steps as well as = an application class to attach start and end event handlers. The even handl= ers are used to place values from the environment into Item Collections and= read results back from Item Collections. |
|
The generated HJ files that manages code to m= ake native invocations into the python implementations using the Babel runt= ime. The user launches the CnC-Python program using a generated script that= invokes the generated HJ main class. |
Back to the example, once the translator completes running there should =
be the following files in the user-code
directory:
class A= pplication: @staticmethod def onStart(args, oddNums): # TODO fill out the body of the function # e.g. operation on output item collections: anItemCollection.put(aTag,= aValue) # e.g. operation on tag collections: aTagCollection.putTag(aTag) pass @staticmethod def onEnd(primes): # TODO fill out the body of the function # e.g. operation on input item collections: anItemCollection.get(aTag) # e.g. operation on input item collections: anItemCollection.printConte= nts() pass
and
class C= omputeStep: @staticmethod def createAwaitsList(tupleContainer, tag ): # TODO fill out the body of the function # e.g. tupleContainer.add(itemCollection, tagValue) # e.g. operation on item collections: anItemCollection.get(aTag) pass @staticmethod def compute(tag , outPrimes): # TODO fill out the body of the function # e.g. operation on input item collections: anItemCollection.get(aTag) # e.g. operation on output item collections: anItemCollection.put(aTag,= aValue) # e.g. operation on tag collections: aTagCollection.putTag(aTag) return True
Rename both files to userFindPrimesApp.py
and userCom=
puteStep.py
. The userFindPrimesApp.py
provides the onEnd
functions. The function signatures =
are determined by detecting the environment interactions in the CnC graph. =
The onStart
function also provides access to any command line =
arguments used while launching the program. The userComputeStep.py file provides the file the user needs to edit to provide the Step impl=
ementation. A Step needs to implement the
createAwaitsList
and=
compute
functions. The createAwaitsList
function=
allows the user to specify the input data dependences on Item Collections.=
Once these dependences have been satisfied the compute
functi=
on will be invoked.
Below are simple implementations for the two python files:
import = time class Application: startTime =3D 0 endTime =3D 0 @staticmethod def onStart(args, oddNums): # e.g. operation on output item collections: anItemCollection.put(aTag,= aValue) # e.g. operation on tag collections: aTagCollection.putTag(aTag) if len(args) > 0: firstArg =3D args[0] print("py: processing " + firstArg) intValue =3D int(firstArg) Application.startTime =3D time.clock() for i in xrange(3, intValue, 2): oddNums.putTag(str(i)) else: print("py: usage FindPrimesMain <num_items>") @staticmethod def onEnd(primes): # e.g. operation on input item collections: anItemCollection.get(aTag) # e.g. operation on input item collections: anItemCollection.printConte= nts() Application.endTime =3D time.clock() elapsedTime =3D int((Application.endTime - Application.startTime) * 100= 0) print "py: Elapsed time:", elapsedTime, "ms" primes.printContents()
and
class C= omputeStep: @staticmethod def createAwaitsList(tupleContainer, tag ): # e.g. tupleContainer.add(itemCollection, tagValue) # e.g. operation on item collections: anItemCollection.get(aTag) # no dependencies, do nothing pass @staticmethod def compute(tag , outPrimes): # e.g. operation on input item collections: anItemCollection.get(aTag) # e.g. operation on output item collections: anItemCollection.put(aTag,= aValue) # e.g. operation on tag collections: aTagCollection.putTag(aTag) candidate =3D int(tag) if ComputeStep.isPrime(candidate): outPrimes.put(str(candidate), candidate) return True @staticmethod def isPrime(n): for k in xrange(3, n, 2): if n % k =3D=3D 0: return False return True
Please refer to the Partition-String example to see an example of =
how to implement the createAwaitsList
function.
Running this program with an input of 100
should produce th=
e following output:
Running= FindPrimesMain Starting FindPrimesMain... ... FindPrimesMain execution time: ... ms. FindPrimesMain ends. py: processing 100 py: Elapsed time: ... ms Contents of py:FindPrimes.PrimesItemCollection [size=3D24] '11' =3D 11 '13' =3D 13 '17' =3D 17 '19' =3D 19 '23' =3D 23 '29' =3D 29 '3' =3D 3 '31' =3D 31 '37' =3D 37 '41' =3D 41 '43' =3D 43 '47' =3D 47 '5' =3D 5 '53' =3D 53 '59' =3D 59 '61' =3D 61 '67' =3D 67 '7' =3D 7 '71' =3D 71 '73' =3D 73 '79' =3D 79 '83' =3D 83 '89' =3D 89 '97' =3D 97