Skip to content

List of common problems

Bill Sacks edited this page May 8, 2020 · 15 revisions

List of common problems to watch out for when developing / reviewing code

Possible sources of model crashes or non-physical results

Potential for divide-by-zero

Solution: put code in a conditional that checks for 0, and handles 0 values specially

Potential for other floating point exceptions (e.g,. raising 0 to a negative power, etc.)

Solution: put code in a conditional that handles mathematically impossible cases specially

Potential for a quantity that should be non-negative to go negative, due to rounding errors

Solution: foo = max(foo, 0._r8)

Possible sources of science bugs and maintainability problems

Block of code is copy & pasted

Solution: Introduce a subroutine that holds the common code

Variable is used on right-hand side of an equation before it has its "final" value

Example:

foo = bar + 1.\_r8

(more code here)

bar = bar + 1.\_r8

In this case, it's possible that the foo assignment should really have happened after the increment to bar.

Solution: Check code carefully for assignments to variables that are used on the right-hand side of equations. Ideally, this search would only need to be done within the current subroutine. But in practice, variables in CLM are sometimes updated in multiple subroutines, so you should extend this search to make sure your new code happens in the correct place in the driver loop. (i.e., make sure that there aren't subroutines called later in the driver that update the quantity that you're using on the right-hand side of the equation.)

Possible sources of threading bugs

Whole-array assignment

foo(:) = 0.\_r8

should be replaced by the following, assuming foo is a column-level array:

foo(bounds%begc:bounds%endc) = 0.\_r8

or, better, initialize foo within a loop over the appropriate filter, or a loop over bounds%begc to bounds%endc, ideally subset by active points.

Improper argument passing

See CLM Coding Conventions#ArgumentPassingargPass

Possible sources of performance problems

Doing an operation on all array elements rather than just active points

Active points are (generally, but not entirely) ones with > 0 weight on the grid cell.

Solution: Use the filters, which only include active points

Nested loops in the wrong order for cache-friendliness and/or vectorizability

Clone this wiki locally