问题
We currently use a mock JIT compiler for CUDA, where nvcc.exe is invoked on some files and the resulting .ptx files are generated.
bool executeWindowsProcess(ofstream &logFF) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
char cmd[] = "\"C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v5.0\\bin\\nvcc.exe\"";
char args[] = "\"C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v5.0\\bin\\nvcc.exe\" --ptx --machine 32 -arch=sm_30 -o C:\\Users\\Yutong\\GOODKERNELCOMPILED.ptx --use_fast_math C:\\Users\\Yutong\\tempkernel.cu";
logFF << cmd << endl;
logFF << args << endl;
CreateProcess(cmd, args, NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi);
logFF << GetLastError() << endl;
WaitForSingleObject(pi.hProcess, INFINITE);
logFF << GetLastError() << endl;
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return true;
}
The first GetLastError() returns 123, which seems to indicate that nvcc.exe isn't invoked at all. Setting cmd[] to something like notepad.exe (which is in C:/Windows/System32/notepad.exe) works fine. I've asked some people, and it seems that:
- My app is deployed for 32-bit Windows
- nvcc.exe is located in C:/Program Files/..../ which is a 64-bit directory, and CreateProcess doesn't seem to be able to invoke executables in directories it doesn't have permission for.
PS, we used to use system() to invoke the JIT compiler, but system() launches an external terminal window (we're writing a GUI) and is generally not recommended.
回答1:
GetLastError()
only has meaning when an actual error occurs. You are not checking the return value of CreateProcess()
to make sure an error actually occurred before then calling GetLastError()
to retrieve it. You need to do so, eg:
bool executeWindowsProcess(ofstream &logFF)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
char cmd[] = "\"C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v5.0\\bin\\nvcc.exe\"";
char args[] = "\"C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v5.0\\bin\\nvcc.exe\" --ptx --machine 32 -arch=sm_30 -o C:\\Users\\Yutong\\GOODKERNELCOMPILED.ptx --use_fast_math C:\\Users\\Yutong\\tempkernel.cu";
logFF << cmd << endl;
logFF << args << endl;
if (!CreateProcess(cmd, args, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi))
{
logFF << GetLastError() << endl;
return false;
}
logFF << "Running" << endl;
WaitForSingleObject(pi.hProcess, INFINITE);
logFF << "Terminated" << endl;
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
return true;
}
With that said, error 123 is ERROR_INVALID_NAME
("The filename, directory name, or volume label syntax is incorrect."). Since you are trying to invoke a command-line, I suggest you set the lpApplicationName
parameter of CreateProcess()
to NULL and just use the lpCommandLine
parameter by itself, eg:
bool executeWindowsProcess(ofstream &logFF)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
char args[] = "\"C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v5.0\\bin\\nvcc.exe\" --ptx --machine 32 -arch=sm_30 -o C:\\Users\\Yutong\\GOODKERNELCOMPILED.ptx --use_fast_math C:\\Users\\Yutong\\tempkernel.cu";
logFF << args << endl;
if (!CreateProcessA(NULL, args, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi))
{
logFF << GetLastError() << endl;
return false;
}
logFF << "Running" << endl;
WaitForSingleObject(pi.hProcess, INFINITE);
logFF << "Terminated" << endl;
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
return true;
}
来源:https://stackoverflow.com/questions/15469666/invoking-nvcc-exe-using-createprocess