Difference in inference time between CUDA 10.0 & 10.2

Carmel_Barak: <p>Hi,<br>
We have a working library that uses LibTorch 1.5.0, built with CUDA 10.0 which runs as expected. We are working on upgrading to CUDA 10.2 for various non-PyTorch related reasons. We noticed that when we run LibTorch inference on the newly compiled LibTorch (compiled exactly the same, except changing to CUDA 10.2), the runtime is about 20x slower.<br>
We also checked it using the precompiled binaries. This was tested on 3 different machines using 3 different GPUs (Tesla T4, GTX980 &amp; P1000) and all gives consistent ~20x slower on CUDA 10.2<br>
(Both on Windows 10 &amp; Ubuntu 16.04), all with the latest drivers</p>
<p>I’ve simplified the code to be extremely minimal without external dependencies other than Torch<br>
Tested also on multiple different torch scripts.</p>
<pre><code class="lang-auto">int main(int argc, char** argv)
{
	// Initialize CUDA device 0
	cudaSetDevice(0);

	std::string networkPath = DEFAULT_TORCH_SCRIPT;
	if (argc &gt; 1)
	{
		networkPath = argv[1];
	}
	auto jitModule = std::make_shared&lt;torch::jit::Module&gt;(torch::jit::load(networkPath, torch::kCUDA));
	if (jitModule == nullptr)
	{
		std::cerr &lt;&lt; "Failed creating module" &lt;&lt; std::endl;
		return EXIT_FAILURE;
	}

        // Meaningless data, just something to pass to the module to run on
        // PATCH_HEIGHT &amp; WIDTH are defined as 256
	uint8_t* data = new uint8_t[PATCH_HEIGHT * PATCH_WIDTH * 3];
	memset(data, 0, PATCH_HEIGHT * PATCH_WIDTH * 3);
	
	auto stream = at::cuda::getStreamFromPool(true, 0);

	bool res = infer(jitModule, stream, data, PATCH_WIDTH, PATCH_HEIGHT);

	std::cout &lt;&lt; "Warmed up" &lt;&lt; std::endl;


	res = infer(jitModule, stream, data, PATCH_WIDTH, PATCH_HEIGHT);

	delete[] data;
	return 0;
}

// Inference function

bool infer(std::shared_ptr&lt;JitModule&gt;&amp; jitModule, at::cuda::CUDAStream&amp; stream, const uint8_t* inputData, int width, int height)
{
	std::vector&lt;torch::jit::IValue&gt; tensorInput;
    // This function simply uses cudaMemcpy to copy to device and create a torch::Tensor from that data 
    // I can paste it if it's relevant but didn't now to keep as clean as possible
	if (!prepareInput(inputData, width, height, tensorInput, stream))
	{
		return false;
	}
	// Reduce memory usage, without gradients
	torch::NoGradGuard noGrad;
	{
		at::cuda::CUDAStreamGuard streamGuard(stream);
		
		auto totalTimeStart = std::chrono::high_resolution_clock::now();

		jitModule-&gt;forward(tensorInput);
		// The synchronize here is just for timing sake, not use in production
		cudaStreamSynchronize(stream.stream());
		
		auto totalTimeStop = std::chrono::high_resolution_clock::now();
		printf("forward sync time = %.3f milliseconds\n",
			std::chrono::duration&lt;double, std::milli&gt;(totalTimeStop - totalTimeStart).count());
	}

	return true;
}
</code></pre>
<p>When compiling this with Torch that was compiled using CUDA 10.0 we get a runtime of 18 ms and when we run it with Torch compiled with CUDA 10.2, we get a runtime of 430 ms</p>
<p>Any thoughts on that?</p>
<blockquote>
<p>Opened an issue for this in <a href="https://github.com/pytorch/pytorch/issues/41852" rel="noopener nofollow ugc">GitHub</a></p>
</blockquote>

ptrblck: <p>Proposed <code>cudnn.benchmark</code> mode in <a href="https://github.com/pytorch/pytorch/issues/41852#issuecomment-662835190">the issue</a>.<br>
Let’s continue the discussion there.</p>