Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved antialiased mean reduction #1300

Merged
merged 1 commit into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions datashader/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ def get_cuda_mutex_call(lock: bool) -> str:

args.extend([local_lk[i] for i in temps])
if antialias:
args.append("aa_factor")
args += ["aa_factor", "prev_aa_factor"]

if local_cuda_mutex and prev_local_cuda_mutex:
# Avoid unnecessary mutex unlock and lock cycle
Expand Down Expand Up @@ -458,7 +458,7 @@ def get_cuda_mutex_call(lock: bool) -> str:
body = [get_cuda_mutex_call(True)] + body + [get_cuda_mutex_call(False)]

if antialias:
signature.insert(0, "aa_factor")
signature = ["aa_factor", "prev_aa_factor"] + signature

if ndims is None:
code = ('def append(x, y, {0}):\n'
Expand Down
2 changes: 1 addition & 1 deletion datashader/glyphs/glyph.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,6 @@ def _expand_aggs_and_cols(append, ndims, antialiased):

# Antialiased append() calls also take aa_factor argument
if antialiased:
aggs_and_cols_len -= 1
aggs_and_cols_len -= 2

return expand_varargs(aggs_and_cols_len)
7 changes: 5 additions & 2 deletions datashader/glyphs/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -967,15 +967,18 @@ def _full_antialias(line_width, overwrite, i, x0, x1, y0, y1,
prev_correction = True
value = 1.0 - _linearstep(0.5*(line_width - aa), halfwidth, distance)
value *= scale
prev_value = 0.0
if prev_correction:
# Already set pixel from previous segment, need to correct it
prev_distance = abs((x-x0)*prev_rightx + (y-y0)*prev_righty)
prev_value = 1.0 - _linearstep(0.5*(line_width - aa), halfwidth, prev_distance)
prev_value *= scale
value = value - prev_value # Correction from previous segment.
if value <= prev_value:
# Have already used a larger value (alpha) for this pixel.
value = 0.0
if value > 0.0:
xx, yy = (y, x) if flip_xy else (x, y)
append(i, xx, yy, value, *aggs_and_cols)
append(i, xx, yy, value, prev_value, *aggs_and_cols)

return _full_antialias

Expand Down
99 changes: 64 additions & 35 deletions datashader/reductions.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,18 +556,18 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
if not isnull(field):
if isnull(agg[y, x]):
agg[y, x] = aa_factor
agg[y, x] = aa_factor - prev_aa_factor
else:
agg[y, x] += aa_factor
agg[y, x] += aa_factor - prev_aa_factor
return 0
return -1

@staticmethod
@ngjit
def _append_antialias_not_self_intersect(x, y, agg, field, aa_factor):
def _append_antialias_not_self_intersect(x, y, agg, field, aa_factor, prev_aa_factor):
if not isnull(field):
if isnull(agg[y, x]) or aa_factor > agg[y, x]:
agg[y, x] = aa_factor
Expand All @@ -582,16 +582,16 @@

@staticmethod
@ngjit
def _append_no_field_antialias(x, y, agg, aa_factor):
def _append_no_field_antialias(x, y, agg, aa_factor, prev_aa_factor):
if isnull(agg[y, x]):
agg[y, x] = aa_factor
agg[y, x] = aa_factor - prev_aa_factor
else:
agg[y, x] += aa_factor
agg[y, x] += aa_factor - prev_aa_factor
return 0

@staticmethod
@ngjit
def _append_no_field_antialias_not_self_intersect(x, y, agg, aa_factor):
def _append_no_field_antialias_not_self_intersect(x, y, agg, aa_factor, prev_aa_factor):
if isnull(agg[y, x]) or aa_factor > agg[y, x]:
agg[y, x] = aa_factor
return 0
Expand All @@ -600,7 +600,7 @@
# GPU append functions
@staticmethod
@nb_cuda.jit(device=True)
def _append_antialias_cuda(x, y, agg, field, aa_factor):
def _append_antialias_cuda(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value):
old = cuda_atomic_nanmax(agg, (y, x), value)
Expand All @@ -610,7 +610,7 @@

@staticmethod
@nb_cuda.jit(device=True)
def _append_no_field_antialias_cuda_not_self_intersect(x, y, agg, aa_factor):
def _append_no_field_antialias_cuda_not_self_intersect(x, y, agg, aa_factor, prev_aa_factor):
if not isnull(aa_factor):
old = cuda_atomic_nanmax(agg, (y, x), aa_factor)
if isnull(old) or old < aa_factor:
Expand All @@ -627,7 +627,7 @@

@staticmethod
@nb_cuda.jit(device=True)
def _append_no_field_antialias_cuda(x, y, agg, aa_factor):
def _append_no_field_antialias_cuda(x, y, agg, aa_factor, prev_aa_factor):
if not isnull(aa_factor):
old = cuda_atomic_nanmax(agg, (y, x), aa_factor)
if isnull(old) or old < aa_factor:
Expand Down Expand Up @@ -658,6 +658,35 @@
return ret


class _count_ignore_antialiasing(count):
"""Count reduction but ignores antialiasing. Used by mean reduction.
"""
def out_dshape(self, in_dshape, antialias, cuda, partitioned):
return dshape(ct.uint32)

def _antialias_stage_2(self, self_intersect, array_module) -> tuple[AntialiasStage2]:
if self_intersect:
return (AntialiasStage2(AntialiasCombination.SUM_1AGG, 0),)
else:
return (AntialiasStage2(AntialiasCombination.SUM_2AGG, 0),)

Check warning on line 671 in datashader/reductions.py

View check run for this annotation

Codecov / codecov/patch

datashader/reductions.py#L671

Added line #L671 was not covered by tests

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
if not isnull(field) and prev_aa_factor == 0.0:
agg[y, x] += 1
return 0
return -1

@staticmethod
@ngjit
def _append_antialias_not_self_intersect(x, y, agg, field, aa_factor, prev_aa_factor):
if not isnull(field) and prev_aa_factor == 0.0:
agg[y, x] += 1
return 0
return -1

Check warning on line 687 in datashader/reductions.py

View check run for this annotation

Codecov / codecov/patch

datashader/reductions.py#L684-L687

Added lines #L684 - L687 were not covered by tests


class by(Reduction):
"""Apply the provided reduction separately per category.

Expand Down Expand Up @@ -809,7 +838,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
if not isnull(field):
if isnull(agg[y, x]) or aa_factor > agg[y, x]:
agg[y, x] = aa_factor
Expand All @@ -824,7 +853,7 @@

@staticmethod
@ngjit
def _append_no_field_antialias(x, y, agg, aa_factor):
def _append_no_field_antialias(x, y, agg, aa_factor, prev_aa_factor):
if isnull(agg[y, x]) or aa_factor > agg[y, x]:
agg[y, x] = aa_factor
return 0
Expand Down Expand Up @@ -926,8 +955,8 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
value = field*aa_factor
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*(aa_factor - prev_aa_factor)
if not isnull(value):
# agg[y, x] cannot be null as initialised to zero.
agg[y, x] += value
Expand All @@ -936,7 +965,7 @@

@staticmethod
@ngjit
def _append_antialias_not_self_intersect(x, y, agg, field, aa_factor):
def _append_antialias_not_self_intersect(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value) and value > agg[y, x]:
# agg[y, x] cannot be null as initialised to zero.
Expand Down Expand Up @@ -1026,8 +1055,8 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
value = field*aa_factor
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*(aa_factor - prev_aa_factor)
if not isnull(value):
if isnull(agg[y, x]):
agg[y, x] = value
Expand All @@ -1038,7 +1067,7 @@

@staticmethod
@ngjit
def _append_antialias_not_self_intersect(x, y, agg, field, aa_factor):
def _append_antialias_not_self_intersect(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value):
if isnull(agg[y, x]) or value > agg[y, x]:
Expand Down Expand Up @@ -1145,7 +1174,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value) and (isnull(agg[y, x]) or value > agg[y, x]):
agg[y, x] = value
Expand Down Expand Up @@ -1190,7 +1219,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value) and (isnull(agg[y, x]) or value > agg[y, x]):
agg[y, x] = value
Expand All @@ -1200,7 +1229,7 @@
# GPU append functions
@staticmethod
@nb_cuda.jit(device=True)
def _append_antialias_cuda(x, y, agg, field, aa_factor):
def _append_antialias_cuda(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value):
old = cuda_atomic_nanmax(agg, (y, x), value)
Expand Down Expand Up @@ -1247,7 +1276,7 @@
``NaN`` values in the column are skipped.
"""
def _build_bases(self, cuda, partitioned):
return (_sum_zero(self.column), count(self.column))
return (_sum_zero(self.column), _count_ignore_antialiasing(self.column))

@staticmethod
def _finalize(bases, cuda=False, **kwargs):
Expand Down Expand Up @@ -1365,7 +1394,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value) and (isnull(agg[y, x]) or value > agg[y, x]):
agg[y, x] = value
Expand Down Expand Up @@ -1403,7 +1432,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value) and (isnull(agg[y, x]) or value > agg[y, x]):
agg[y, x] = value
Expand Down Expand Up @@ -1512,7 +1541,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value):
# Check final value first for quick abort.
Expand Down Expand Up @@ -1549,7 +1578,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value):
# Always inserts at front of agg's third dimension.
Expand Down Expand Up @@ -1584,7 +1613,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value):
# Linear walk along stored values.
Expand Down Expand Up @@ -1664,7 +1693,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
value = field*aa_factor
if not isnull(value):
# Linear walk along stored values.
Expand Down Expand Up @@ -1841,7 +1870,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor, update_index):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor, update_index):
# Ignore aa_factor.
if agg.ndim > 2:
shift_and_insert(agg[y, x], field, update_index)
Expand All @@ -1850,7 +1879,7 @@

@staticmethod
@nb_cuda.jit(device=True)
def _append_antialias_cuda(x, y, agg, field, aa_factor, update_index):
def _append_antialias_cuda(x, y, agg, field, aa_factor, prev_aa_factor, update_index):
# Ignore aa_factor
if agg.ndim > 2:
cuda_shift_and_insert(agg[y, x], field, update_index)
Expand Down Expand Up @@ -2172,7 +2201,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
# field is int64 row index
# Ignore aa_factor
if field > agg[y, x]:
Expand Down Expand Up @@ -2230,7 +2259,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
# field is int64 row index
# Ignore aa_factor
if field != -1 and (agg[y, x] == -1 or field < agg[y, x]):
Expand Down Expand Up @@ -2326,7 +2355,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
# field is int64 row index
# Ignoring aa_factor
if field != -1:
Expand Down Expand Up @@ -2409,7 +2438,7 @@

@staticmethod
@ngjit
def _append_antialias(x, y, agg, field, aa_factor):
def _append_antialias(x, y, agg, field, aa_factor, prev_aa_factor):
# field is int64 row index
# Ignoring aa_factor
if field != -1:
Expand Down
Loading