Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

generate more verbose error messages on kernel failure

  • Loading branch information...
commit 8ca7cdb36df8279b70470ee8e8548fc60e5b4018 1 parent e942332
@sherhut sherhut authored
View
2  jslib/jit/compiler/driver.js
@@ -135,7 +135,7 @@ RiverTrail.compiler = (function () {
try {
ast = parse(paSource, construct, rankOrShape, f.toString(), args, lowPrecision); // parse, no code gen
- kernelString = RiverTrail.compiler.codeGen(ast, paSource, rankOrShape, construct); // Creates an OpenCL kernel function
+ kernelString = RiverTrail.compiler.codeGen.compile(ast, paSource, rankOrShape, construct); // Creates an OpenCL kernel function
} catch (e) {
RiverTrail.Helper.debugThrow(e);
}
View
51 jslib/jit/compiler/genOCL.js
@@ -50,10 +50,12 @@ if (RiverTrail === undefined) {
RiverTrail.compiler.codeGen = (function() {
const verboseDebug = false;
const checkBounds = true;
+ const verboseErrors = true;
const parser = Narcissus.parser;
const definitions = Narcissus.definitions;
const tokens = RiverTrail.definitions.tokens;
+
// Set constants in the local scope.
eval(definitions.consts);
eval(RiverTrail.definitions.consts);
@@ -64,14 +66,28 @@ RiverTrail.compiler.codeGen = (function() {
var findSelectionRoot = RiverTrail.Helper.findSelectionRoot;
+ // store to hold error messages
+ var errorMsgs = [];
+
+ var newError = function newError(msg) {
+ if (verboseErrors) {
+ errorMsgs[errorMsgs.length] = "AT " + (calledScope.inCalledScope() || "<top level>") + ": " + msg;
+ }
+ return errorMsgs.length; // this is one after the index on purpose!
+ };
+
+ var getError = function getError(number) {
+ return errorMsgs[number-1] || "unknown error";
+ };
+
// If you are working inside the top level of actual kernel function then scope is empty.
// If you generating code for a called function then this will be true.
var calledScope = function () {
"use strict";
// state is private.
var state = false;
- var enter = function enter() {
- state = true;
+ var enter = function enter(name) {
+ state = name || true;
};
var exit = function exit(previous) {
state = previous;
@@ -282,7 +298,7 @@ RiverTrail.compiler.codeGen = (function() {
}
var previousCalledScope = calledScope.inCalledScope();
- calledScope.enter();
+ calledScope.enter(ast.name);
// Need code here to deal with array values being returned.
// NOTE: use dispatched function name here
s = s + " " +ast.typeInfo.result.OpenCLType + " " + ast.dispatch;
@@ -312,7 +328,7 @@ RiverTrail.compiler.codeGen = (function() {
var s = "";
var previousCalledScope = calledScope.inCalledScope();
- calledScope.enter();
+ calledScope.enter(ast.name);
if (ast.value != "function") {
throw "expecting function found " + ast.value;
}
@@ -376,7 +392,7 @@ RiverTrail.compiler.codeGen = (function() {
" double **asPtr = (double **) asInt[0];" +
" unsigned int len = ((unsigned int*) (asPtr[3]-2))[2];" +
" if (exp_len != len) {" +
- " *_FAIL = 42;" +
+ " *_FAIL = " + newError("JavaScript native array argument was not homogeneous") + "; " +
" return (__global double *) 0;" +
" } else {" +
" return (__global double *) asPtr[3];" +
@@ -418,7 +434,7 @@ RiverTrail.compiler.codeGen = (function() {
" double **asPtr = (double **) (asLong & 0x00007FFFFFFFFFFFLL);" +
" unsigned int len = ((unsigned int*) (asPtr[3]-2))[2];" +
" if (exp_len != len) {" +
- " *_FAIL = 42;" +
+ " *_FAIL = " + newError("JavaScript native array argument was not homogeneous") + "; " +
" return (__global double *) 0;" +
" } else {" +
" return (__global double *) asPtr[3];" +
@@ -918,9 +934,9 @@ RiverTrail.compiler.codeGen = (function() {
// This variable should be declared at the top-level of the
// function.
//
- // As a side effect, the global variable _FAIL is set to 1
+ // As a side effect, the global variable _FAIL is set to > 0
// if a bounds check failed.
- function wrapIntoCheck(range, bound, expr) {
+ function wrapIntoCheck(range, bound, expr, ast) {
var postfix = "";
var result = "";
var dynCheck = false;
@@ -935,7 +951,7 @@ RiverTrail.compiler.codeGen = (function() {
((range.lb === undefined) ||
(range.lb < 0))) {
// emit lower bound check
- result += "(_sel_idx_tmp < 0 ? (_FAIL = 2, 0) : ";
+ result += "(_sel_idx_tmp < 0 ? (_FAIL ? 0 : (_FAIL = " + newError("index " + expr + " smaller than zero in " + RiverTrail.Helper.wrappedPP(ast)) + ", 0)) : ";
postfix = ")" + postfix;
dynCheck = true;
}
@@ -944,7 +960,7 @@ RiverTrail.compiler.codeGen = (function() {
((range.ub === undefined) ||
(range.ub >= bound))) {
// emit upper bound check
- result += "(_sel_idx_tmp >= " + bound + " ? (_FAIL = 3, 0) : ";
+ result += "(_sel_idx_tmp >= " + bound + " ? (_FAIL ? 0: (_FAIL = " + newError("index " + expr + " greater than upper bound " + bound + " in " + RiverTrail.Helper.wrappedPP(ast)) + ", 0)) : ";
postfix = ")" + postfix;
dynCheck = true;
}
@@ -985,9 +1001,9 @@ RiverTrail.compiler.codeGen = (function() {
rangeInfo = arrayOfIndices.rangeInfo;
if (elemRank === 0) {
// scalar case
- s = s + "__JS_array_sel_S(" + oclExpression(source) + ", " + wrapIntoCheck(rangeInfo, sourceShape[0], oclExpression(arrayOfIndices)) + ")";
+ s = s + "__JS_array_sel_S(" + oclExpression(source) + ", " + wrapIntoCheck(rangeInfo, sourceShape[0], oclExpression(arrayOfIndices), ast) + ")";
} else {
- s = s + "__JS_array_sel_A(" + oclExpression(source) + ", " + wrapIntoCheck(rangeInfo, sourceShape[0], oclExpression(arrayOfIndices)) + ", " + sourceShape[1] + ", &_FAIL)";
+ s = s + "__JS_array_sel_A(" + oclExpression(source) + ", " + wrapIntoCheck(rangeInfo, sourceShape[0], oclExpression(arrayOfIndices), ast) + ", " + sourceShape[1] + ", &_FAIL)";
}
} else {
// C style arrays
@@ -1016,10 +1032,10 @@ RiverTrail.compiler.codeGen = (function() {
// we have a single scalar index from an INDEX op
rangeInfo = arrayOfIndices.rangeInfo;
if(isParallelArray || isGlobal) {
- s = s + " + " + stride + " * ("+wrapIntoCheck(rangeInfo, sourceShape[0], oclExpression(arrayOfIndices)) + ")";
+ s = s + " + " + stride + " * ("+wrapIntoCheck(rangeInfo, sourceShape[0], oclExpression(arrayOfIndices), ast) + ")";
}
else {
- s = s + "[" + wrapIntoCheck(rangeInfo, sourceShape[0], oclExpression(arrayOfIndices)) + "]";
+ s = s + "[" + wrapIntoCheck(rangeInfo, sourceShape[0], oclExpression(arrayOfIndices), ast) + "]";
}
} else {
// this is a get
@@ -1034,9 +1050,9 @@ RiverTrail.compiler.codeGen = (function() {
for (i = sourceRank - elemRank - 1; i >= 0; i--) { // Ususally only 2 or 3 dimensions so ignore complexity
s = s + " + " + stride + " * ("
if (dynamicSel) {
- s = s + wrapIntoCheck(rangeInfo.get(0).get(i), sourceShape[i], oclExpression(arrayOfIndices.children[0]) + "[" + i + "]") + ")";
+ s = s + wrapIntoCheck(rangeInfo.get(0).get(i), sourceShape[i], oclExpression(arrayOfIndices.children[0], ast) + "[" + i + "]") + ")";
} else {
- s = s + wrapIntoCheck(rangeInfo.get(i), sourceShape[i], oclExpression(arrayOfIndices.children[i])) + ")";
+ s = s + wrapIntoCheck(rangeInfo.get(i), sourceShape[i], oclExpression(arrayOfIndices.children[i]), ast) + ")";
}
stride = stride * sourceType.getOpenCLShape()[i];
}
@@ -1732,6 +1748,5 @@ RiverTrail.compiler.codeGen = (function() {
return s;
}
- return genKernel;
-
+ return {"compile" : genKernel, "getError" : getError};
}());
View
2  jslib/jit/compiler/runOCL.js
@@ -243,7 +243,7 @@ RiverTrail.compiler.runOCL = function () {
}
if (kernelFailure) {
// a more helpful error message would be nice. However, we don't know why it failed. A better exception model is asked for...
- throw new Error("kernel execution failed, probably due to an array out of bounds access.");
+ throw new Error("kernel execution failed: " + RiverTrail.compiler.codeGen.getError(kernelFailure));
}
} else {
alert("runOCL only deals with comprehensions, map and combine (so far).");
Please sign in to comment.
Something went wrong with that request. Please try again.