使用 CreateProcess 调用 nvcc.exe

Posted

技术标签:

【中文标题】使用 CreateProcess 调用 nvcc.exe【英文标题】:Invoking nvcc.exe using CreateProcess 【发布时间】:2013-03-18 04:17:29 【问题描述】:

我们目前为 CUDA 使用模拟 JIT 编译器,其中对某些文件调用 nvcc.exe 并生成生成的 .ptx 文件。

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;

第一个 GetLastError() 返回 123,这似乎表明根本没有调用 nvcc.exe。将 cmd[] 设置为诸如 notepad.exe(位于 C:/Windows/System32/notepad.exe 中)之类的东西可以正常工作。我问了一些人,似乎是:

    我的应用是为 32 位 Windows 部署的 nvcc.exe 位于 C:/Program Files/..../ 这是一个 64 位目录,并且 CreateProcess 似乎无法调用它没有权限的目录中的可执行文件。

PS,我们曾经使用 system() 来调用 JIT 编译器,但是 system() 会启动一个外部终端窗口(我们正在编写一个 GUI),因此通常不推荐使用。

【问题讨论】:

你是想在这里提问吗? 【参考方案1】:

GetLastError() 仅在发生实际错误时才有意义。您没有检查 CreateProcess() 的返回值以确保在调用 GetLastError() 之前确实发生了错误以检索它。你需要这样做,例如:

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;

话虽如此,错误 123 是 ERROR_INVALID_NAME(“文件名、目录名或卷标语法不正确。”)。由于您正在尝试调用命令行,我建议您将CreateProcess()lpApplicationName 参数设置为NULL,并单独使用lpCommandLine 参数,例如:

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;

【讨论】:

您好,这是一个很好的答案!似乎确实将所有内容移至命令行是可行的。我们工作流程的一部分还通过“2>”将所有内容通过管道传输到日志文件,这会破坏事情 - 不知道如何处理这个问题。 \"C:\\Program Files\\NVIDIA GPU 计算工具包\\CUDA\\v5.0\\bin\\nvcc.exe\" --ptx --machine 32 -arch=sm_30 -o C:\\Users \\宇通\\GOODKERNELCOMPILED.ptx --use_fast_math C:\\Users\\宇通\\tempkernel.cu 2> log.txt 您不能像这样使用带有CreateProcess() 的命令行管道。您必须要么 1) 通过 CreatePipe() 创建自己的 STDOUT 句柄并将其提供给 CreateProcess(),然后手动读取 nvcc 的输出并将其写入自己的文件,或者 2) 没有 CreateProcess() 调用 nvcc.exe直接,让它调用 cmd.exe ,将/C 参数传递给它以指定它要执行的完整命令行,包括管道。使用%COMSPEC% 环境变量找到cmd.exe 的完整路径。 不幸的是 CMD /C 选项不起作用,我认为甚至不允许使用“>”字符。我现在正在寻找如何做管道(但它看起来很丑)。 @proteneer:是的,您可以在 cmd.exe 中使用 &gt; 字符。我刚刚测试了它,它工作得很好。我能够使用"&lt;full path to&gt;\cmd.exe" /C &lt;command line&gt; &gt; log.txt 将输出重定向到.txt 文件。其实正是因为是经过cmd.exe,所以完全可以使用命令行重定向,因为&gt;是命令处理器的一部分。 谢谢!我让它工作了=)我很懒惰,只是传入 %COMPSPEC% 而不是完全限定(扩展)到 cmd 的路径

以上是关于使用 CreateProcess 调用 nvcc.exe的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CreateProcess 函数正确调用“telnet”?

使用 createprocess() 调用时,Windows 的 wget 会忽略选项

调用 CreateProcess() 并获取字符串的返回值

在 CreateProcess 之后调用 GetModuleFileNameEx 时出现 ERROR_INVALID_HANDLE

无法使用 nvcc 找到 Torch 头文件

pyinstallerexe无法createprocess调用