Cycles: improve error reporting for opencl and cuda, showing error messages in
viewport instead of only console.
This commit is contained in:
parent
055ddbc22d
commit
086e4ed825
@ -76,6 +76,7 @@ protected:
|
||||
Device() {}
|
||||
|
||||
bool background;
|
||||
string error_msg;
|
||||
|
||||
public:
|
||||
virtual ~Device() {}
|
||||
@ -84,6 +85,7 @@ public:
|
||||
|
||||
/* info */
|
||||
virtual string description() = 0;
|
||||
const string& error_message() { return error_msg; }
|
||||
|
||||
/* regular memory */
|
||||
virtual void mem_alloc(device_memory& mem, MemoryType type) = 0;
|
||||
|
@ -122,7 +122,10 @@ public:
|
||||
CUresult result = stmt; \
|
||||
\
|
||||
if(result != CUDA_SUCCESS) { \
|
||||
fprintf(stderr, "CUDA error: %s in %s\n", cuda_error_string(result), #stmt); \
|
||||
string message = string_printf("CUDA error: %s in %s", cuda_error_string(result), #stmt); \
|
||||
if(error_msg == "") \
|
||||
error_msg = message; \
|
||||
fprintf(stderr, "%s\n", message.c_str()); \
|
||||
cuda_abort(); \
|
||||
} \
|
||||
}
|
||||
@ -132,10 +135,20 @@ public:
|
||||
if(result == CUDA_SUCCESS)
|
||||
return false;
|
||||
|
||||
fprintf(stderr, "CUDA error: %s\n", cuda_error_string(result));
|
||||
string message = string_printf("CUDA error: %s", cuda_error_string(result));
|
||||
if(error_msg == "")
|
||||
error_msg = message;
|
||||
fprintf(stderr, "%s\n", message.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void cuda_error(const string& message)
|
||||
{
|
||||
if(error_msg == "")
|
||||
error_msg = message;
|
||||
fprintf(stderr, "%s\n", message.c_str());
|
||||
}
|
||||
|
||||
void cuda_push_context()
|
||||
{
|
||||
cuda_assert(cuCtxSetCurrent(cuContext))
|
||||
@ -224,14 +237,14 @@ public:
|
||||
return cubin;
|
||||
|
||||
#ifdef WITH_CUDA_BINARIES
|
||||
fprintf(stderr, "CUDA binary kernel for this graphics card not found.\n");
|
||||
cuda_error("CUDA binary kernel for this graphics card not found.");
|
||||
return "";
|
||||
#else
|
||||
/* if not, find CUDA compiler */
|
||||
string nvcc = cuCompilerPath();
|
||||
|
||||
if(nvcc == "") {
|
||||
fprintf(stderr, "CUDA nvcc compiler not found. Install CUDA toolkit in default location.\n");
|
||||
cuda_error("CUDA nvcc compiler not found. Install CUDA toolkit in default location.");
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -251,13 +264,13 @@ public:
|
||||
nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), maxreg, include.c_str());
|
||||
|
||||
if(system(command.c_str()) == -1) {
|
||||
fprintf(stderr, "Failed to execute compilation command.\n");
|
||||
cuda_error("Failed to execute compilation command, see console for details.");
|
||||
return "";
|
||||
}
|
||||
|
||||
/* verify if compilation succeeded */
|
||||
if(!path_exists(cubin)) {
|
||||
fprintf(stderr, "CUDA kernel compilation failed.\n");
|
||||
cuda_error("CUDA kernel compilation failed, see console for details.");
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -284,7 +297,7 @@ public:
|
||||
|
||||
CUresult result = cuModuleLoad(&cuModule, cubin.c_str());
|
||||
if(cuda_error(result))
|
||||
fprintf(stderr, "Failed loading CUDA kernel %s.\n", cubin.c_str());
|
||||
cuda_error(string_printf("Failed loading CUDA kernel %s.", cubin.c_str()));
|
||||
|
||||
cuda_pop_context();
|
||||
|
||||
|
@ -109,17 +109,30 @@ public:
|
||||
bool opencl_error(cl_int err)
|
||||
{
|
||||
if(err != CL_SUCCESS) {
|
||||
fprintf(stderr, "OpenCL error (%d): %s\n", err, opencl_error_string(err));
|
||||
string message = string_printf("OpenCL error (%d): %s", err, opencl_error_string(err));
|
||||
if(error_msg == "")
|
||||
error_msg = message;
|
||||
fprintf(stderr, "%s\n", message.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void opencl_error(const string& message)
|
||||
{
|
||||
if(error_msg == "")
|
||||
error_msg = message;
|
||||
fprintf(stderr, "%s\n", message.c_str());
|
||||
}
|
||||
|
||||
void opencl_assert(cl_int err)
|
||||
{
|
||||
if(err != CL_SUCCESS) {
|
||||
fprintf(stderr, "OpenCL error (%d): %s\n", err, opencl_error_string(err));
|
||||
string message = string_printf("OpenCL error (%d): %s", err, opencl_error_string(err));
|
||||
if(error_msg == "")
|
||||
error_msg = message;
|
||||
fprintf(stderr, "%s\n", message.c_str());
|
||||
#ifndef NDEBUG
|
||||
abort();
|
||||
#endif
|
||||
@ -147,7 +160,7 @@ public:
|
||||
return;
|
||||
|
||||
if(num_platforms == 0) {
|
||||
fprintf(stderr, "OpenCL: no platforms found.\n");
|
||||
opencl_error("OpenCL: no platforms found.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -183,24 +196,24 @@ public:
|
||||
clGetPlatformInfo(cpPlatform, CL_PLATFORM_VERSION, sizeof(version), &version, NULL);
|
||||
|
||||
if(sscanf(version, "OpenCL %d.%d", &major, &minor) < 2) {
|
||||
fprintf(stderr, "OpenCL: failed to parse platform version string (%s).", version);
|
||||
opencl_error(string_printf("OpenCL: failed to parse platform version string (%s).", version));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!((major == req_major && minor >= req_minor) || (major > req_major))) {
|
||||
fprintf(stderr, "OpenCL: platform version 1.1 or later required, found %d.%d\n", major, minor);
|
||||
opencl_error(string_printf("OpenCL: platform version 1.1 or later required, found %d.%d", major, minor));
|
||||
return false;
|
||||
}
|
||||
|
||||
clGetDeviceInfo(cdDevice, CL_DEVICE_OPENCL_C_VERSION, sizeof(version), &version, NULL);
|
||||
|
||||
if(sscanf(version, "OpenCL C %d.%d", &major, &minor) < 2) {
|
||||
fprintf(stderr, "OpenCL: failed to parse OpenCL C version string (%s).", version);
|
||||
opencl_error(string_printf("OpenCL: failed to parse OpenCL C version string (%s).", version));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!((major == req_major && minor >= req_minor) || (major > req_major))) {
|
||||
fprintf(stderr, "OpenCL: C version 1.1 or later required, found %d.%d\n", major, minor);
|
||||
opencl_error(string_printf("OpenCL: C version 1.1 or later required, found %d.%d", major, minor));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -216,7 +229,7 @@ public:
|
||||
vector<uint8_t> binary;
|
||||
|
||||
if(!path_read_binary(clbin, binary)) {
|
||||
fprintf(stderr, "OpenCL failed to read cached binary %s.\n", clbin.c_str());
|
||||
opencl_error(string_printf("OpenCL failed to read cached binary %s.", clbin.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -229,7 +242,7 @@ public:
|
||||
&size, &bytes, &status, &ciErr);
|
||||
|
||||
if(opencl_error(status) || opencl_error(ciErr)) {
|
||||
fprintf(stderr, "OpenCL failed create program from cached binary %s.\n", clbin.c_str());
|
||||
opencl_error(string_printf("OpenCL failed create program from cached binary %s.", clbin.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -253,7 +266,7 @@ public:
|
||||
clGetProgramInfo(cpProgram, CL_PROGRAM_BINARIES, sizeof(uint8_t*), &bytes, NULL);
|
||||
|
||||
if(!path_write_binary(clbin, binary)) {
|
||||
fprintf(stderr, "OpenCL failed to write cached binary %s.\n", clbin.c_str());
|
||||
opencl_error(string_printf("OpenCL failed to write cached binary %s.", clbin.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -293,7 +306,8 @@ public:
|
||||
clGetProgramBuildInfo(cpProgram, cdDevice, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
|
||||
|
||||
build_log[ret_val_size] = '\0';
|
||||
fprintf(stderr, "OpenCL build failed:\n %s\n", build_log);
|
||||
opencl_error("OpenCL build failed: errors in console");
|
||||
fprintf(stderr, "%s\n", build_log);
|
||||
|
||||
delete[] build_log;
|
||||
|
||||
|
@ -203,6 +203,10 @@ void Session::run_gpu()
|
||||
if(!no_tiles) {
|
||||
/* update scene */
|
||||
update_scene();
|
||||
|
||||
if(device->error_message() != "")
|
||||
progress.set_cancel(device->error_message());
|
||||
|
||||
if(progress.get_cancel())
|
||||
break;
|
||||
}
|
||||
@ -222,6 +226,9 @@ void Session::run_gpu()
|
||||
|
||||
device->task_wait();
|
||||
|
||||
if(device->error_message() != "")
|
||||
progress.set_cancel(device->error_message());
|
||||
|
||||
if(progress.get_cancel())
|
||||
break;
|
||||
}
|
||||
@ -243,6 +250,9 @@ void Session::run_gpu()
|
||||
}
|
||||
}
|
||||
|
||||
if(device->error_message() != "")
|
||||
progress.set_cancel(device->error_message());
|
||||
|
||||
if(progress.get_cancel())
|
||||
break;
|
||||
}
|
||||
@ -345,6 +355,10 @@ void Session::run_cpu()
|
||||
|
||||
/* update scene */
|
||||
update_scene();
|
||||
|
||||
if(device->error_message() != "")
|
||||
progress.set_cancel(device->error_message());
|
||||
|
||||
if(progress.get_cancel())
|
||||
break;
|
||||
|
||||
@ -360,6 +374,9 @@ void Session::run_cpu()
|
||||
|
||||
if(!params.background)
|
||||
need_tonemap = true;
|
||||
|
||||
if(device->error_message() != "")
|
||||
progress.set_cancel(device->error_message());
|
||||
}
|
||||
|
||||
device->task_wait();
|
||||
@ -379,6 +396,9 @@ void Session::run_cpu()
|
||||
want to show the result of an incomplete sample*/
|
||||
tonemap();
|
||||
}
|
||||
|
||||
if(device->error_message() != "")
|
||||
progress.set_cancel(device->error_message());
|
||||
}
|
||||
|
||||
progress.set_update();
|
||||
@ -391,7 +411,11 @@ void Session::run()
|
||||
progress.set_status("Loading render kernels (may take a few minutes the first time)");
|
||||
|
||||
if(!device->load_kernels()) {
|
||||
progress.set_status("Failed loading render kernel, see console for errors");
|
||||
string message = device->error_message();
|
||||
if(message == "")
|
||||
message = "Failed loading render kernel, see console for errors";
|
||||
|
||||
progress.set_status("Error", message);
|
||||
progress.set_update();
|
||||
return;
|
||||
}
|
||||
@ -409,7 +433,7 @@ void Session::run()
|
||||
|
||||
/* progress update */
|
||||
if(progress.get_cancel())
|
||||
progress.set_status(progress.get_cancel_message());
|
||||
progress.set_status("Cancel", progress.get_cancel_message());
|
||||
else
|
||||
progress.set_update();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user