delite: emitDeliteArray don't generate some headers for cuda and cpp

30 views
Skip to first unread message

Alexander Samoilov

unread,
Mar 28, 2015, 12:37:22 PM3/28/15
to opt...@googlegroups.com
Hello All!

I encountered the following problem:
[info]   java.lang.RuntimeException: cuda compilation failed with exit value 2 (log in compile.log)

$ less compile.log
... generatedCache/cuda/src/datastructures/cudaTuple2DeliteArrayDoubleInt.h:3:35: fatal error: cudaDeliteArraydouble.h: No such file or directory
 #include "cudaDeliteArraydouble.h"

Indeed the mentioned header has not been generated by codegen.
The same problem has occurred for other types say DeliteArray<int32_t>
and for cpp as well, that is not only for cuda.
Could you please help to fix the problem?

Thanks!
Alexander

Alexander Samoilov

unread,
Mar 31, 2015, 11:51:57 AM3/31/15
to opt...@googlegroups.com
Hello Again,

Let me expand on the question.
The root cause of the failure is: the needed files were created, then deleted on the next iteration of the loop (when the whole directory was swept) but the hash map with the information about created headers has not been cleared.

Let me carry away and focus on the next problem, the contention one that causes an exception:

[info]   Cause: java.lang.UnsatisfiedLinkError: Native Library /home/alsam/work/scalan-cuda-codegen/generatedCache/cuda/bin/runtime/cudaHostddmvm_1010.so already loaded in another classloader

The .so resource captured by

object Executable1 extends DeliteExecutable {
@native def hostExecutable1: Unit
  System.load("""/home/alsam/work/scalan-cuda-codegen/generatedCache/cuda/bin/runtime/cudaHostddmvm_1010.so""")

has never been released

A naive attempt just to catch an exception:

--- a/delite/runtime/src/ppl/delite/runtime/codegen/CppExecutableGenerator.scala
+++ b/delite/runtime/src/ppl/delite/runtime/codegen/CppExecutableGenerator.scala
@@ -237,14 +237,27 @@ class ScalaNativeExecutableGenerator(override val location: Int, override val gr
     val configString = Config.numThreads.toString + Config.numCpp + Config.numCuda + Config.numOpenCL
     val tgt = OpHelper.scheduledTarget(location)
     out.append("@native def host" + executableName(location) + ": Unit\n")
-    out.append("System.load(\"\"\"")
-    out.append(Compilers(tgt).binCacheHome + tgt + "Host" + appName + "_" + configString + "." + OS.libExt)
+    out.append("try {\n")
+    out.append("  System.load(\"\"\"")
+    val libpath = Compilers(tgt).binCacheHome + tgt + "Host" + appName + "_" + configString + "." + OS.libExt
+    out.append(libpath)
     out.append("\"\"\")\n")
+    out.append("} catch {\n")
+    out.append("  case _ => println(\"\"\"")
+    out.append("-W- an exception occurred while loading " + libpath)
+    out.append("\"\"\")\n")
+    out.append("}\n")
   }
 
   private def writeNativeCall() {
-    out.append("host")
+    out.append("try {\n")
+    out.append("  host")
     out.append(executableName(location))
     out.append('\n')
+    out.append("} catch {\n")
+    out.append("  case _ => println(\"\"\"")
+    out.append("-W- an exception occurred while calling a native executable")
+    out.append("\"\"\")\n")
+    out.append("}\n")
   }
 }

leads to a race condition, to deadlock to be more exact.

I looked into the ExecutionThread.scala code and noticed:

  protected def loadNative(fileName: String, compiler: CCompile) = {
    val sep = File.separator
    val root = compiler.staticResources + fileName
    val path = root + "." + OS.libExt
    val lib = new File(path)
    if (!lib.exists) compiler.compileInit(root)
    System.load(path) //TODO: doesn't work properly with sbt test suite
  }

What would you recommend to override it?

Thanks!
Alexander

HyoukJoong Lee

unread,
Apr 1, 2015, 7:41:50 AM4/1/15
to opt...@googlegroups.com
Hi Alexander,

Have you been experiencing the problem when running the test suite?
Or is it even when running delite/delitec normally?
We had some bugs of not clearing up the previous run's artifacts when running the test suite.
This was in part because a set of tests are executed within a same jvm process by the test framework,
and when two tests happen to use the same name for the generated .so file that needs to be loaded during delite runtime execution,
the classloader complains when it tries to load it for the second time.
There was no easy way to unload a native library, so we made the name of the generated .so file to be different for different runtime configurations.
1010 in your case represents the number of resources used for Scala, C++, Cuda, and OpenCL respectively, which helps to avoid naming conflicts when we run our test.

Cheers,
HyoukJoong


--
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/d/optout.

Alexander Samoilov

unread,
Apr 3, 2015, 6:54:25 AM4/3/15
to opt...@googlegroups.com
Hi HyoukJoong,

Thanks for your clarification and for a piece of advice!
I've been experiencing the problem when running the test suite.
I invoke the staged program in a loop several times.
I'll follow your advice and either rename the case by adding the iteration number as a suffix or maybe rewrite JNI generator code.

Cheers,
Alexander
Reply all
Reply to author
Forward
0 new messages