报错如下:
filtered_lrelu.cpp(147): error C4984: 'if constexpr' is a C++17 language extension
原因是我用的Visual studio 2017里的编译器好像是C++14的标准,但是这个语句是C++17的。自动学完C++就再也没碰过,所以只能摸索着整。尝试装了2022版本的VS,但是CUDA 11.1编译只支持2017和2019的,官方给的installer里又没有2019。后来在stylegan3的官方库里找到一个issue是有大哥碰到了这个问题并解决了:
https://github.com/NVlabs/stylegan3/issues/38
在这里记录一下解决的方法:
(1) 在/torch_utils/ops/filtered_lrelu.h里加入
template < typename T >
struct ScalarTypeLessThan4 {
using type = T;
};
template <>
struct ScalarTypeLessThan4 < double > {
using type = float;
};
(2) 在/torch_utils/ops/filtered_lrelu.cpp中,把大概157行的这一段,也就是出问题的地方
if constexpr (sizeof(scalar_t) <= 4) // Exclude doubles. constexpr prevents template instantiation.
{
using scalar_t_l4 = ScalarTypeLessThan4<scalar_t>::type;
// Choose kernel based on index type, datatype and sign read/write modes.
if (!index64b && writeSigns && !readSigns) spec = choose_filtered_lrelu_kernel<scalar_t, int32_t, true, false>(p, sharedKB);
else if (!index64b && !writeSigns && readSigns) spec = choose_filtered_lrelu_kernel<scalar_t, int32_t, false, true >(p, sharedKB);
else if (!index64b && !writeSigns && !readSigns) spec = choose_filtered_lrelu_kernel<scalar_t, int32_t, false, false>(p, sharedKB);
else if ( index64b && writeSigns && !readSigns) spec = choose_filtered_lrelu_kernel<scalar_t, int64_t, true, false>(p, sharedKB);
else if ( index64b && !writeSigns && readSigns) spec = choose_filtered_lrelu_kernel<scalar_t, int64_t, false, true >(p, sharedKB);
else if ( index64b && !writeSigns && !readSigns) spec = choose_filtered_lrelu_kernel<scalar_t, int64_t, false, false>(p, sharedKB);
}
替换为:
if /*constexpr*/ (sizeof(scalar_t) <= 4) // Exclude doubles. constexpr prevents template instantiation.
{
using scalar_t_l4 = ScalarTypeLessThan4<scalar_t>::type;
// Choose kernel based on index type, datatype and sign read/write modes.
if (!index64b && writeSigns && !readSigns) spec = choose_filtered_lrelu_kernel<scalar_t_l4, int32_t, true, false>(p, sharedKB);
else if (!index64b && !writeSigns && readSigns) spec = choose_filtered_lrelu_kernel<scalar_t_l4, int32_t, false, true >(p, sharedKB);
else if (!index64b && !writeSigns && !readSigns) spec = choose_filtered_lrelu_kernel<scalar_t_l4, int32_t, false, false>(p, sharedKB);
else if ( index64b && writeSigns && !readSigns) spec = choose_filtered_lrelu_kernel<scalar_t_l4, int64_t, true, false>(p, sharedKB);
else if ( index64b && !writeSigns && readSigns) spec = choose_filtered_lrelu_kernel<scalar_t_l4, int64_t, false, true >(p, sharedKB);
else if ( index64b && !writeSigns && !readSigns) spec = choose_filtered_lrelu_kernel<scalar_t_l4, int64_t, false, false>(p, sharedKB);
}
然后就可以顺利运行啦!
附一张生成的图