Reputation: 4062
Yesterday I figured out that one can control the command line process by redirecting the standard input and writing to it, but now I have a problem that unlike when launching a process directly, if I call the Nvidia NVCC compiler via the command prompt, I do not get any direct reply whether the compilation was successful.
Rather, the F# app I am controlling the command prompt from only sees text and I won't even get a reply for when compilation is done unless I build a parser for the output stream or something to that effect.
The least labor intensive way of getting what I want seems to be using FileSystemWatcher to notify me when the .ptx
file is created so I can load it into the program then, but I do not know much about the command prompt, so I thought to ask here whether there are any better solutions than this.
It would be great if I could do something like pass a callback into it instead. Maybe instead of using the standard Ms-Dos prompt, the newer Windows Powershell has some better interfacing features?
Upvotes: 1
Views: 161
Reputation: 4062
To whom it may be of interest, I decided to go with vitalygolub's idea for my neural net library. Here is how it looks like:
open System
open System.Diagnostics
open System.IO
let compile_kernel_using_nvcc_bat_router kernel_code kernel_name =
let nvcc_router_path = Path.Combine(kernels_dir,"nvcc_router.bat")
use p =
let procStartInfo =
ProcessStartInfo(
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
FileName = nvcc_router_path)
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
let quote x = sprintf "\"%s\"" x
let call x = sprintf "call %s" x
let quoted_vs_path_to_vcvars = Path.Combine(visual_studio_path, @"VC\bin\x86_amd64\vcvarsx86_amd64.bat") |> quote
let quoted_vs_path_to_cl = Path.Combine(visual_studio_path, @"VC\bin\x86_amd64") |> quote
let quoted_cuda_toolkit_path_to_include = Path.Combine(cuda_toolkit_path,"include") |> quote
let quoted_kernels_dir = kernels_dir |> quote
let target_path = Path.Combine(kernels_dir,kernel_name+".ptx")
let quoted_target_path = target_path |> quote
let input_path = Path.Combine(kernels_dir,"_temp.cu")
let quoted_input_path = input_path |> quote
File.WriteAllText(input_path,kernel_code)
let _ =
use nvcc_router_file = File.OpenWrite(nvcc_router_path)
use nvcc_router_stream = new StreamWriter(nvcc_router_file)
nvcc_router_stream.WriteLine(call quoted_vs_path_to_vcvars)
nvcc_router_stream.WriteLine(
sprintf
"""nvcc -gencode=arch=compute_30,code=\"sm_30,compute_30\" --use-local-env --cl-version 2015 -ccbin %s -I%s --keep-dir %s -maxrregcount=0 --machine 64 -ptx -cudart static -o %s %s"""
quoted_vs_path_to_cl quoted_cuda_toolkit_path_to_include quoted_kernels_dir quoted_target_path quoted_input_path)
if p.Start() = false then failwith "NVCC failed to run."
p.BeginOutputReadLine()
p.BeginErrorReadLine()
p.WaitForExit()
if p.ExitCode <> 0 then failwithf "NVCC failed compilation with code %i" p.ExitCode
cuda_context.LoadKernelPTX(target_path,kernel_name)
Calling .bat
files from a .bat
file requires using the call
command for legacy reasons. Apart from that it works quite well and terminates with error codes other than zero when compilation fails and outputs the error to the error stream. The input stream handler is commented out on purpose.
Upvotes: 1