I agree with Tom. At the top level of the netlist (which is the reference point for the "param=" statement on the .sens line), it will not understand the parameter names on the subcircuit definition line. The same goes for .params defined inside a subcircuit; internally they are basically the same as the .params on the definition line.
In principle, one *could* make it so that the "param=" statement on the .sens line would understand these, but they would need to be fully resolved to include the subcircuit name. So, if that were to happen, the fully resolved parameter names for the x4 subcircuit instance would be things like param=x4:v1,x4:v2,x4:v3,x4:v4.
However, this currently isn't implemented in Xyce. Historically, the only parameters that are allowed to vary during a simulation are parameters that are set in the top level of the netlist. And, currently when doing sensitivities based on .param parameters, it is necessary to perform finite differences to obtain the device derivative. ie, the "df/dp" term in the dO/dp = dO/dx * (df/dx)^-1 * df/dp chain rule.
To perform a finite difference derivative with respect to a .param, that param must be mutable, so currently this only applies at the top level of the netlist.
Interestingly, in some recent developments there have been some exceptions to this "top level only" rule. That is for the case of global vs. local variation in random operators such as {agauss}. To support that properly it was necessary to modify Xyce to allow (in the use case of sampling and/or other UQ methods) to allow subcircuit internal parameters to be mutable. But, at the time that I did that work it didn't occur to me to apply this same exception to sensitivity analysis, so currently it doesn't do that.
By the way, in our local copy of Xyce I've fixed the issue that prevented .param-based direct sensitivities from working with VPWL sources. So, that works now equivalently to using them with B-sources. Whenever we do the next merge to the public repository you'll see that fix. That fix was very simple, and just involved adding two lines of code to one function.
I've also started to work on making .param-sensitivities work for transient adjoints, but that is a more involved fix, so it won't be published right away.
thanks,
Eric