a) !$acc region
Sure. If statements can be part of the device kernel. The caveat is that your performance may suffer due to divergence. GPU Threads are organized in groups called ‘warps’. Each thread in a warp executes the same instructions at the same time, just on different data (SIMD, single instructions multiple data). So if your threads diverge by taking different paths in an if statement, all the threads still need to execute the same instructions. This means that some of the threads will need throw away the instruction and wait for there turn. While they issue their instructions, the other threads will need to wait.
So if statements are fine so long as all the threads in a warp take the same path. Otherwise, you’ll hurt your performance.
b) !$acc data region
Doesn’t matter since the if statement in this case is host code. Any host code can be used within a data region. The only thing to keep in mind is which copy of the data, host or device, you are acting on. For example, if you copyin an array via a data region, then set the array to some value in the host code, the device code will not be set. You would then need to use the “!$acc update device” directive to copy the new value of the array to the device.
Hope this helps,