问题
To compile a Cuda kernel from the command line, two things are necessary. The first is to run the vsvars
batch file like so:
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat"
The second is to actually invoke the compiler:
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -gencode=arch=compute_30,code=\"sm_30,compute_30\" --use-local-env --cl-version 2015 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" --keep-dir "C:\Users\Marko\Documents\Visual Studio 2015\Projects\Multi-armed Bandit Experiments\NVCC Experiments\x64\Release" -maxrregcount=0 --machine 64 -ptx -cudart static -o "C:\Users\Marko\Documents\Visual Studio 2015\Projects\Multi-armed Bandit Experiments\NVCC Experiments\x64\Release\kernel.cu.obj" "C:\Users\Marko\Documents\Visual Studio 2015\Projects\Multi-armed Bandit Experiments\NVCC Experiments\kernel.cu"
I want to do the above not from the command line, but from an F# script or an executable, but am not sure how to do the first step. The second is well documented on MSDN though; it can be done using the Process class.
As an aside, the Cuda library does have the runtime equivalent of the NVCC compiler called NVRTC which I've been using up to now, but it lacks some crucial features such as lambdas, tuples and access to other Cuda libraries. I wanted lambdas and tuples so much that I even made my own F# quotations to Cuda compiler, but doing it like this would be better than operating under self imposed constraints.
Any ideas how I can add that local environment before calling NVCC? Also, it would be interesting if the process could be reused.
回答1:
open System
open System.Diagnostics
let procStartInfo =
ProcessStartInfo(
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UseShellExecute = false,
FileName = "cmd"
)
let outputHandler f (_sender:obj) (args:DataReceivedEventArgs) = f args.Data
let p = new Process(StartInfo = procStartInfo)
let print_to_standard_output = outputHandler <| fun x -> printfn "%s" x
p.OutputDataReceived.AddHandler(DataReceivedEventHandler (print_to_standard_output))
p.ErrorDataReceived.AddHandler(DataReceivedEventHandler (print_to_standard_output))
p.Start()
p.BeginOutputReadLine()
p.BeginErrorReadLine()
p.StandardInput.WriteLine """ "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" """
p.StandardInput.WriteLine """ "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -gencode=arch=compute_30,code=\"sm_30,compute_30\" --use-local-env --cl-version 2015 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" --keep-dir "C:\Users\Marko\Documents\Visual Studio 2015\Projects\Multi-armed Bandit Experiments\NVCC Experiments\x64\Release" -maxrregcount=0 --machine 64 -ptx -cudart static -o "C:\Users\Marko\Documents\Visual Studio 2015\Projects\Multi-armed Bandit Experiments\NVCC Experiments\x64\Release\kernel.cu.obj" "C:\Users\Marko\Documents\Visual Studio 2015\Projects\Multi-armed Bandit Experiments\NVCC Experiments\kernel.cu" """
As it turns out, it is possible to redirect the standard input and control the shell from within the program that way. The above code fragment is adapted from the one on the MSDN page to do what I wanted - run the batch file to bring in the environment and then run the NVCC compiler.
来源:https://stackoverflow.com/questions/40745894/how-to-add-a-local-environment-to-a-process-in-net