runjob hooks can change the values of resources. When doing so, they don't call the resource's action function (when it should). Action functions are mainly used to validate values. The following resources have an action function the makes sure the value is >= 0: ncpus, mpiprocs, ompthreads, mppwidth, mppdepth, mppnppn. The preempt_targets resource has an action function that validates its value as well.
Any of those resources can be set negative in a hook.
See the following:
% cat run.py
e = pbs.event()
j = e.job
j.Resource_List["ncpus"] = -1
% qsub -l ncpus=1 – /bin/sleep 10000
% qstat -f | grep ncpus
Resource_List.ncpus = -1
Resource_List.select = 1:ncpus=-1
schedselect = 1:ncpus=-1
Submit_arguments = -l ncpus=1 – /bin/sleep 10000
ncpus is now set to -1.