For transforms that require expensive state (like a plan or a handle), use a cache to improve performance. This avoids re-creating the state for every call with the same signature.
To implement caching:
- Define a Params Key: A struct containing all parameters that define the transform's state (e.g., dimensions, strides, stream, execution type).
- Implement a Hash function (
FftCUDAParamsKeyHash): Provides a quick hash for initial map lookups. - Implement an Equality function (
FftCUDAParamsKeyEq): Performs a full comparison of all parameters once a hash match is found to ensure a true cache hit. - Use
detail::GetCache().LookupAndExec<CacheType>(...) in your impl function. This method takes the cache ID, the parameters, a factory function to create the cached object on a miss, and an execution function to run the transform on a hit.
Example of the LookupAndExec pattern:
using cache_val_type = detail::matxCUDAFFTPlan1D_t<decltype(out), decltype(in)>;
detail::GetCache().LookupAndExec<detail::fft_cuda_cache_t>(
detail::GetCacheIdFromType<detail::fft_cuda_cache_t>(),
params,
[&]() {
return std::make_shared<cache_val_type>(out, in, stream);
},
[&](std::shared_ptr<cache_val_type> ctype) {
ctype->Forward(out, in, stream, norm);
}
);
using cache_val_type = detail::matxCUDAFFTPlan1D_t<decltype(out), decltype(in)>;
detail::GetCache().LookupAndExec<detail::fft_cuda_cache_t>(
detail::GetCacheIdFromType<detail::fft_cuda_cache_t>(),
params,
[&]() {
return std::make_shared<cache_val_type>(out, in, stream);
},
[&](std::shared_ptr<cache_val_type> ctype) {
ctype->Forward(out, in, stream, norm);
}
);