Using OptiML with "scopes"?

58 views
Skip to first unread message

Aaron Todd

unread,
Mar 1, 2013, 1:01:02 PM3/1/13
to opt...@googlegroups.com

The FAQ has a section on using a feature called "scopes" to use OptiML pieces in a larger more general application as a way to efficiently use CUDA from Scala. It also says to send an e-mail to get more info, so here is an e-mail.

"The second approach is to use OptiML and Delite's support for scopes, coarse-grained execution blocks that are compiled, staged, and executed independently. This feature is experimental and still under development, but it allows users to pass values into and out of staged blocks from surrounding ordinary Scala (or other DSL) code." [1]

Thanks,
  ~ Aaron Todd

Arvind Sujeeth

unread,
Mar 4, 2013, 8:52:30 PM3/4/13
to opt...@googlegroups.com
Scopes allow you to write code like the following:

import ppl.dsl.optiml.OptiML

object MyApp {
def main(args: Array[String]) {
// unstaged code
println("1")

// staged code
OptiML {
val v = Vector.rand(100)
val b = v*v*v
println(b(0))
}
}
}

(Here, "OptiML" is the scope). "MyApp" is an ordinary Scala program.
When the scope constructor executes, it will actually stage, execute,
and run the snippet inside. The only tricky part to getting this running
(besides the non-trivial latency of staging and executing the scope) is
to make sure that you run "MyApp" with the right classpaths (you need
the Delite framework, OptiML, and runtime components all in the classpath).

Since this is experimental, we don't have an out-of-the-box solution for
scope communication or compilation ready yet for the optiml-beta branch.
We do have methods for doing this and an entire solution to make this
process smooth for end users (including scripts and documentation) will
come online in the next couple of months.. it's just in the back-log of
stuff we're doing right now. If you want to roll your own script to set
up the classpaths, though, and you don't need inter-scope communication,
you can use the scope feature right now.

Arvind
> --
> You received this message because you are subscribed to the Google
> Groups "OptiML" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to optiml+un...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Aaron Todd

unread,
Mar 5, 2013, 12:19:39 PM3/5/13
to opt...@googlegroups.com
Ok, sounds like a great feature that just isn't ready yet. I don't think I'll want scopes for the use I have planned, but if I change my mind I'll update this thread to get some assistance writing those classpath scripts.

Thanks,
  ~ Aaron Todd

Yarco Hayduk

unread,
Jul 28, 2014, 11:24:27 AM7/28/14
to opt...@googlegroups.com
Do you have any updates with regard to using Scopes?
I looked around and only found some high level info in the ECOOP13 paper describing their usage.

Thank you,
Yarco

Arvind Sujeeth

unread,
Jul 29, 2014, 12:09:08 PM7/29/14
to opt...@googlegroups.com
hi Yarco,

Check out https://github.com/stanford-ppl/Forge/blob/master/apps/OptiML/src/Examples.scala, Example14 and Example15. They show how to use scopes, similar to how they are described in the ECOOP paper.

I'm afraid they are not particularly robust at this point. While simple examples work, more complicated examples may fail to stage. This is because we have not yet handled all of the corner cases in transforming the DSL IRs to the generic parallel IR.

Another option we have recently added is to generate jar files from compiled DSL code, so you can rewrite a performance-critical portion of your code in a DSL, generate a jar for that function, and then link that in to your Scala or Java program. Kevin might be able to say a little more about this.

cheers,
Arvind
For more options, visit https://groups.google.com/d/optout.

Yarco Hayduk

unread,
Jul 31, 2014, 10:14:22 AM7/31/14
to opt...@googlegroups.com
Hi Arvind,

Thank you for giving me a few pointers.

As far as I understand, the code in Example14 needs to be compiled with scala-virtualized?
You indicated that scopes are not robust at this point. Does this also apply to the case when I generate a jar and call its code (by the way, does this force me to use scala-virtualized for the calling code?) from the outside world. When calling the jar code from the outside world (Scala), would that require to use scala-virtualized?
If it is not too difficult, would you mind providing a (very basic) example on how you would call OptiML code packed in a jar? You also mentioned that you need to have the "Delite framework, OptiML, and runtime components all in the classpath"; which exact runtime components are required?

I hope I did not overflow you with questions... My main goal is to try to use OptiML-generated code as performance-critical code from an external Scala application. We want to receive input data from another machine (possibly via RMI) and then process it with OptiML-generated Scala/CUDA code. As a start, we want to receive data via RMI and run kMeans on it.

Thank you for your help,
Yarco

Arvind Sujeeth

unread,
Jul 31, 2014, 1:53:08 PM7/31/14
to opt...@googlegroups.com, Kevin Brown
hi Yarco,

Yes, the code in the examples needs to be compiled with scala-virtualized. The SBT project included with Delite will automatically download the compiler.

I have not used the jar functionality myself yet, so I'm afraid I can't offer an example. (Kevin, do you have an example?) However, scala-virtualized will only be needed when compiling and generating the jar; in the project that links in the jar, an ordinary Scala compiler can be used. The jar contains compiled generated code, and our Scala generated code is ordinary Scala that does not require scala-virtualized.

Arvind

Kevin Brown

unread,
Jul 31, 2014, 11:48:20 PM7/31/14
to opt...@googlegroups.com

Hi,

You can find an example application using this feature at

https://github.com/stanford-ppl/Forge/blob/master/apps/OptiGraph/src/CommunityDetection.scala


To make this work with any other app you just need to add the two extra lines in the Compiler object.  The first overrides ‘main’ as the function that you want the compiler to use as the entry point to your app.  The second defines the name for that function that your external scala code will use to call it.

While this will work for any function, in practice you'll want to restrict the input/output types of the function to primitives (Int, Double, etc.) String, and ForgeArray, as these are the types that have direct translations to the corresponding scala types in the generated code.  

You then call delitec on your app the same as always.  After that call delite and add two extra options: ‘—jar’ and ‘—walk-only’.  The first tells the runtime to save the generated code in a jar and the second stops it from trying to run the app immediately.

You should now see a jar named after your app in your working directory.  To run the app you need to add this jar and the runtime jar to your classpath.

If you’re using the binary version of optiml you’ll find the jar called runtime in the lib directory.  If you’re using optiml from source you can generate it by running 

sbt “; project runtime; publish-local” 

in the delite repository directory.

You should now be able to call the generated app directly from any scala or java code using the name you defined.  We generate the entry point as a scala Function so you can call it and pass it around just like any other function object.

—Kevin

Yarco Hayduk

unread,
Aug 26, 2014, 11:53:42 AM8/26/14
to opt...@googlegroups.com
Thank you for the pointers, Kevin!
I am having more problems, unfortunately.

I generated the OptiGraph DSL using

forge/bin/update ppl.dsl.forge.dsls.optigraph.OptiGraphDSLRunner OptiGraph

and then ran

bin/delitec CommunityDetectionCompiler 
bin/delite CommunityDetectionCompiler

from the 'published/OptiGraph' folder

delitec goes through just fine but whenever I run delite (with and without ‘—jar’ and ‘—walk-only’) I get a lengthy exception:
http://pastebin.com/Y4hKcvNr

I checked out recent versions of delite/forge and performed the steps described in the 'Getting started from source' section of the web page.

Please advise

Thank you,
Yarco

Kevin Brown

unread,
Aug 28, 2014, 2:57:15 AM8/28/14
to opt...@googlegroups.com
These kind of errors can happen sometimes when the runtime's code cache gets corrupted.  We're working on fixing this, but in the short term manually deleting the 'generatedCache' folder in the delite directory should solve the problem.  If it doesn't then somehow the 'generated' directory and the .deg file contain two different programs (deleting them both and starting over is the best option to fix that too).  
I should warn you that OptiGraph is our newest DSL and still under heavy development, so I'm not entirely sure how stable it is at the moment.  However the piece that overrides which function to compile is provided by Delite itself and therefore works the exact same way for OptiML as well.

--Kevin 

Yarco Hayduk

unread,
Aug 28, 2014, 8:39:09 AM8/28/14
to opt...@googlegroups.com
Hi Kevin,

I tried your suggestion - same thing. I even checked out a clean copy of hyperdsl to double check. I still get the following error when trying to 'delite' CommunityDetection
http://pastebin.com/g5gHip1s

Since you said that the steps that are required for scopes are generic and can be used for any DSL, I retrofitted the OptiML k-means example for working with scopes, in the following way:
http://pastebin.com/fjTiWjEU

When I uncomment the
//override def functionName = "kMeansExtRun";

part, I get the following error:
http://pastebin.com/vc0viuXJ

I also regularly run
rm -rf ./../delite/generatedCache/ kMeansCompilerExt.deg generated MeansCompilerExt-bin.jar
from the
published/OptiML
folder to prevent cache problems.

If I leave the functionName part commented, the code example compiles and generates a jar file. I, however, don't know which function to instantiate from the external Scala code, having that jar + runtime jar in the classpath.

Thank you for your help with this,
Yarco

 

Yarco Hayduk

unread,
Aug 28, 2014, 9:46:09 AM8/28/14
to opt...@googlegroups.com
Hi again, Kevin

We managed to run the kmeans example using the generated DeliteApplication object in the jar.
As a next step, we tried running

bin/delitec kMeansCompilerExt --cuda
//which succeeds

and then
bin/delite kMeansCompilerExt --walk-only --jar --cuda 1
//which throws http://pastebin.com/M29xt99T

Is it at all possible to call cuda-generated delite code packed in a jar from an external Scala app?

Thank you again,
Yarco

Kevin Brown

unread,
Aug 28, 2014, 11:29:10 AM8/28/14
to opt...@googlegroups.com
I'm glad you got it working. We currently only support scala execution from the jar as we haven't yet implemented a way to automatically load the native code and copy the inputs out of the jvm. 

--Kevin

Yarco Hayduk

unread,
Aug 28, 2014, 12:07:49 PM8/28/14
to opt...@googlegroups.com
Thank you for your help, Kevin!

Looking forward to testing new releases of Delite/OptiML.

Yarco
Reply all
Reply to author
Forward
0 new messages