Skip to content

Commit 7547a89

Browse files
authored
Add cube root function to the language (#1164)
Also added a special case to allow pow(x,1.0/3.0) to be automatically turned into cbrt during runtime optimziation.
1 parent 0d5bc28 commit 7547a89

File tree

10 files changed

+72
-1
lines changed

10 files changed

+72
-1
lines changed

src/doc/languagespec.tex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3025,6 +3025,11 @@ \subsection{Mathematical functions}
30253025
Computes $\sqrt{x}$ and $1/\sqrt{x}$. Returns 0 if $x<0$.
30263026
\apiend
30273027

3028+
\apiitem{\emph{type} {\ce cbrt} (\emph{type} x) \\
3029+
\indexapi{cbrt()}
3030+
Computes $\sqrt[3]{x}$. The sign of the return value will match $x$.
3031+
\apiend
3032+
30283033
\apiitem{float {\ce hypot} (float x, float y) \\
30293034
float {\ce hypot} (float x, float y, float z)}
30303035
\indexapi{hypot()}

src/include/OSL/dual.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,29 @@ OSL_HOSTDEVICE OSL_FORCEINLINE Dual<T,P> inversesqrt (const Dual<T,P> &a)
12371237
return result;
12381238
}
12391239

1240+
// f(x) = cbrt(x), f'(x) = -1/(3*x^(2/3))
1241+
template<class T, int P>
1242+
OSL_HOSTDEVICE OSL_FORCEINLINE Dual<T,P> cbrt (const Dual<T,P> &a)
1243+
{
1244+
if (OSL_LIKELY(a.val() != T(0))) {
1245+
T f = std::cbrt(a.val());
1246+
T df = T(-1) / (T(3) * f * f);
1247+
return dualfunc(a, f, df);
1248+
}
1249+
return Dual<T,P> (T(0));
1250+
}
1251+
1252+
template<class T, int P>
1253+
OSL_HOSTDEVICE OSL_FORCEINLINE Dual<T,P> fast_cbrt (const Dual<T,P> &a)
1254+
{
1255+
if (OSL_LIKELY(a.val() != T(0))) {
1256+
T f = OIIO::fast_cbrt(float(a.val())); // float version!
1257+
T df = T(-1) / (T(3) * f * f);
1258+
return dualfunc(a, f, df);
1259+
}
1260+
return Dual<T,P> (T(0));
1261+
}
1262+
12401263
// (fx) = x*(1-a) + y*a, f'(x) = (1-a)x' + (y - x)*a' + a*y'
12411264
template<class T, int P>
12421265
OSL_HOSTDEVICE OSL_FORCEINLINE Dual<T,P> mix (const Dual<T,P> &x, const Dual<T,P> &y, const Dual<T,P> &a)

src/liboslexec/builtindecl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ DECL (osl_pow_dvdvf, "xXXf")
260260

261261
UNARY_OP_IMPL(sqrt)
262262
UNARY_OP_IMPL(inversesqrt)
263+
UNARY_OP_IMPL(cbrt)
263264

264265
DECL (osl_logb_ff, "ff")
265266
DECL (osl_logb_vv, "xXX")

src/liboslexec/constfold.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ static ustring u_nop ("nop"),
2929
u_mul ("mul"),
3030
u_sqrt ("sqrt"),
3131
u_inversesqrt ("inversesqrt"),
32+
u_cbrt ("cbrt"),
3233
u_if ("if"),
3334
u_eq ("eq"),
3435
u_return ("return"),
@@ -1811,6 +1812,7 @@ AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (expm1 , OIIO::fast_expm1)
18111812
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (log , OIIO::fast_log)
18121813
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (log10 , OIIO::fast_log10)
18131814
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (log2 , OIIO::fast_log2)
1815+
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (cbrt , OIIO::fast_cbrt)
18141816
#else
18151817
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (cos , cosf)
18161818
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (sin , sinf)
@@ -1822,6 +1824,7 @@ AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (expm1 , expm1f)
18221824
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (log , OIIO::safe_log)
18231825
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (log10 , OIIO::safe_log10)
18241826
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (log2 , OIIO::safe_log2)
1827+
AUTO_DECLFOLDER_FLOAT_OR_TRIPLE (cbrt , cbrtf)
18251828
#endif
18261829

18271830
DECLFOLDER(constfold_pow)
@@ -1885,6 +1888,11 @@ DECLFOLDER(constfold_pow)
18851888
"pow(x,-0.5) => inversesqrt(x)");
18861889
return 1;
18871890
}
1891+
if (yval == 1.0f / 3.0f) {
1892+
rop.turn_into_new_op (op, u_cbrt, resultarg, xarg, -1,
1893+
"pow(x,1.0/3.0) => cbrt(x)");
1894+
return 1;
1895+
}
18881896
}
18891897

18901898
return 0;

src/liboslexec/llvm_ops.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ MAKE_BINARY_PERCOMPONENT_OP (pow , OIIO::fast_safe_pow , fast_safe_po
493493
MAKE_BINARY_PERCOMPONENT_VF_OP (pow , OIIO::fast_safe_pow , fast_safe_pow)
494494
MAKE_UNARY_PERCOMPONENT_OP (erf , OIIO::fast_erf , fast_erf)
495495
MAKE_UNARY_PERCOMPONENT_OP (erfc , OIIO::fast_erfc , fast_erfc)
496+
MAKE_UNARY_PERCOMPONENT_OP (cbrt , OIIO::fast_cbrt , fast_cbrt)
496497
#else
497498
MAKE_UNARY_PERCOMPONENT_OP (log , OIIO::safe_log , safe_log)
498499
MAKE_UNARY_PERCOMPONENT_OP (log2 , OIIO::safe_log2 , safe_log2)
@@ -504,6 +505,7 @@ MAKE_BINARY_PERCOMPONENT_OP (pow , OIIO::safe_pow , safe_pow)
504505
MAKE_BINARY_PERCOMPONENT_VF_OP (pow , OIIO::safe_pow , safe_pow)
505506
MAKE_UNARY_PERCOMPONENT_OP (erf , erff , erf)
506507
MAKE_UNARY_PERCOMPONENT_OP (erfc , erfcf , erfc)
508+
MAKE_UNARY_PERCOMPONENT_OP (cbrt , cbrtf , cbrt)
507509
#endif
508510

509511
MAKE_UNARY_PERCOMPONENT_OP (sqrt , OIIO::safe_sqrt , sqrt)

src/liboslexec/shadingsys.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,7 @@ shading_system_setup_op_descriptors (ShadingSystemImpl::OpDescriptorMap& op_desc
867867
OP (blackbody, blackbody, none, true, 0);
868868
OP (break, loopmod_op, none, false, 0);
869869
OP (calculatenormal, calculatenormal, none, true, 0);
870+
OP (cbrt, generic, cbrt, true, 0);
870871
OP (ceil, generic, ceil, true, 0);
871872
OP (cellnoise, noise, noise, true, 0);
872873
OP (clamp, clamp, clamp, true, 0);

src/shaders/stdosl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ PERCOMP1 (log10)
9797
PERCOMP1 (logb)
9898
PERCOMP1 (sqrt)
9999
PERCOMP1 (inversesqrt)
100+
PERCOMP1 (cbrt)
100101
float hypot (float a, float b) { return sqrt (a*a + b*b); }
101102
float hypot (float a, float b, float c) { return sqrt (a*a + b*b + c*c); }
102103
PERCOMP1 (abs)

testsuite/function-redef/ref/out.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
test.osl:5: warning: Function 'point abs (point)' redefined in the same scope
22
Previous definitions:
3-
stdosl.h:102
3+
stdosl.h:103
44
test.osl:15: warning: Function 'int redclfunc (int)' redefined in the same scope
55
Previous definitions:
66
test.osl:14

testsuite/miscmath/ref/out.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Compiled test.osl -> test.oso
1111
sign (101.29) = 1
1212
sqrt (101.29) = 10.0643
1313
inversesqrt (101.29) = 0.0993612
14+
cbrt (101.29) = 4.66146
1415
fmod (101.29, 151.935) = 101.29
1516
fabs (-137.59) = 137.59
1617
floor (-137.59) = -138
@@ -20,6 +21,7 @@ Compiled test.osl -> test.oso
2021
sign (-137.59) = -1
2122
sqrt (-137.59) = 0
2223
inversesqrt (-137.59) = 0
24+
cbrt (-137.59) = -5.16253
2325
mod (16, 7) = 2
2426
fmod (16, 7) = 2
2527
mod (16, 7) = 2
@@ -33,6 +35,7 @@ Compiled test.osl -> test.oso
3335
sign (101.29 101.29 101.29) = 1 1 1
3436
sqrt (101.29 101.29 101.29) = 10.0643 10.0643 10.0643
3537
inversesqrt (101.29 101.29 101.29) = 0.0993612 0.0993612 0.0993612
38+
cbrt (101.29 101.29 101.29) = 4.66146 4.66146 4.66146
3639
fmod (101.29 101.29 101.29, 151.935 151.935 151.935) = 101.29 101.29 101.29
3740
fabs (-137.59 -137.59 -137.59) = 137.59 137.59 137.59
3841
floor (-137.59 -137.59 -137.59) = -138 -138 -138
@@ -42,6 +45,7 @@ Compiled test.osl -> test.oso
4245
sign (-137.59 -137.59 -137.59) = -1 -1 -1
4346
sqrt (-137.59 -137.59 -137.59) = 0 0 0
4447
inversesqrt (-137.59 -137.59 -137.59) = 0 0 0
48+
cbrt (-137.59 -137.59 -137.59) = -5.16253 -5.16253 -5.16253
4549
fmod (-137.59 -137.59 -137.59, -206.385 -206.385 -206.385) = -137.59 -137.59 -137.59
4650
mod (-137.59 -137.59 -137.59, -206.385 -206.385 -206.385) = -137.59 -137.59 -137.59
4751
varying:
@@ -53,6 +57,7 @@ Compiled test.osl -> test.oso
5357
sign (0) = 0
5458
sqrt (0) = 0
5559
inversesqrt (0) = 0
60+
cbrt (0) = 0
5661
fmod (0, 0) = 0
5762
mod (0, 0) = 0
5863
fabs (0 0 0) = 0 0 0
@@ -63,6 +68,7 @@ Compiled test.osl -> test.oso
6368
sign (0 0 0) = 0 0 0
6469
sqrt (0 0 0) = 0 0 0
6570
inversesqrt (0 0 0) = 0 0 0
71+
cbrt (0 0 0) = 0 0 0
6672
fmod (0 0 0, 0 0 0) = 0 0 0
6773
mod (0 0 0, 0 0 0) = 0 0 0
6874
abs (137) = 137
@@ -77,6 +83,7 @@ Compiled test.osl -> test.oso
7783
sign (101.29) = 1
7884
sqrt (101.29) = 10.0643
7985
inversesqrt (101.29) = 0.0993612
86+
cbrt (101.29) = 4.66146
8087
fmod (101.29, 151.935) = 101.29
8188
fabs (-137.59) = 137.59
8289
floor (-137.59) = -138
@@ -86,6 +93,7 @@ Compiled test.osl -> test.oso
8693
sign (-137.59) = -1
8794
sqrt (-137.59) = 0
8895
inversesqrt (-137.59) = 0
96+
cbrt (-137.59) = -5.16253
8997
mod (16, 7) = 2
9098
fmod (16, 7) = 2
9199
mod (16, 7) = 2
@@ -99,6 +107,7 @@ Compiled test.osl -> test.oso
99107
sign (101.29 101.29 101.29) = 1 1 1
100108
sqrt (101.29 101.29 101.29) = 10.0643 10.0643 10.0643
101109
inversesqrt (101.29 101.29 101.29) = 0.0993612 0.0993612 0.0993612
110+
cbrt (101.29 101.29 101.29) = 4.66146 4.66146 4.66146
102111
fmod (101.29 101.29 101.29, 151.935 151.935 151.935) = 101.29 101.29 101.29
103112
fabs (-137.59 -137.59 -137.59) = 137.59 137.59 137.59
104113
floor (-137.59 -137.59 -137.59) = -138 -138 -138
@@ -108,6 +117,7 @@ Compiled test.osl -> test.oso
108117
sign (-137.59 -137.59 -137.59) = -1 -1 -1
109118
sqrt (-137.59 -137.59 -137.59) = 0 0 0
110119
inversesqrt (-137.59 -137.59 -137.59) = 0 0 0
120+
cbrt (-137.59 -137.59 -137.59) = -5.16253 -5.16253 -5.16253
111121
fmod (-137.59 -137.59 -137.59, -206.385 -206.385 -206.385) = -137.59 -137.59 -137.59
112122
mod (-137.59 -137.59 -137.59, -206.385 -206.385 -206.385) = -137.59 -137.59 -137.59
113123
varying:
@@ -119,6 +129,7 @@ Compiled test.osl -> test.oso
119129
sign (1) = 1
120130
sqrt (1) = 1
121131
inversesqrt (1) = 1
132+
cbrt (1) = 1
122133
fmod (1, 1.5) = 1
123134
mod (1, 1.5) = 1
124135
fabs (1 1 1) = 1 1 1
@@ -129,6 +140,7 @@ Compiled test.osl -> test.oso
129140
sign (1 1 1) = 1 1 1
130141
sqrt (1 1 1) = 1 1 1
131142
inversesqrt (1 1 1) = 1 1 1
143+
cbrt (1 1 1) = 1 1 1
132144
fmod (1 1 1, 1.5 1.5 1.5) = 1 1 1
133145
mod (1 1 1, 1.5 1.5 1.5) = 1 1 1
134146
abs (137) = 137
@@ -143,6 +155,7 @@ Compiled test.osl -> test.oso
143155
sign (101.29) = 1
144156
sqrt (101.29) = 10.0643
145157
inversesqrt (101.29) = 0.0993612
158+
cbrt (101.29) = 4.66146
146159
fmod (101.29, 151.935) = 101.29
147160
fabs (-137.59) = 137.59
148161
floor (-137.59) = -138
@@ -152,6 +165,7 @@ Compiled test.osl -> test.oso
152165
sign (-137.59) = -1
153166
sqrt (-137.59) = 0
154167
inversesqrt (-137.59) = 0
168+
cbrt (-137.59) = -5.16253
155169
mod (16, 7) = 2
156170
fmod (16, 7) = 2
157171
mod (16, 7) = 2
@@ -165,6 +179,7 @@ Compiled test.osl -> test.oso
165179
sign (101.29 101.29 101.29) = 1 1 1
166180
sqrt (101.29 101.29 101.29) = 10.0643 10.0643 10.0643
167181
inversesqrt (101.29 101.29 101.29) = 0.0993612 0.0993612 0.0993612
182+
cbrt (101.29 101.29 101.29) = 4.66146 4.66146 4.66146
168183
fmod (101.29 101.29 101.29, 151.935 151.935 151.935) = 101.29 101.29 101.29
169184
fabs (-137.59 -137.59 -137.59) = 137.59 137.59 137.59
170185
floor (-137.59 -137.59 -137.59) = -138 -138 -138
@@ -174,6 +189,7 @@ Compiled test.osl -> test.oso
174189
sign (-137.59 -137.59 -137.59) = -1 -1 -1
175190
sqrt (-137.59 -137.59 -137.59) = 0 0 0
176191
inversesqrt (-137.59 -137.59 -137.59) = 0 0 0
192+
cbrt (-137.59 -137.59 -137.59) = -5.16253 -5.16253 -5.16253
177193
fmod (-137.59 -137.59 -137.59, -206.385 -206.385 -206.385) = -137.59 -137.59 -137.59
178194
mod (-137.59 -137.59 -137.59, -206.385 -206.385 -206.385) = -137.59 -137.59 -137.59
179195
varying:
@@ -185,6 +201,7 @@ Compiled test.osl -> test.oso
185201
sign (0) = 0
186202
sqrt (0) = 0
187203
inversesqrt (0) = 0
204+
cbrt (0) = 0
188205
fmod (0, 0) = 0
189206
mod (0, 0) = 0
190207
fabs (0 0 0) = 0 0 0
@@ -195,6 +212,7 @@ Compiled test.osl -> test.oso
195212
sign (0 0 0) = 0 0 0
196213
sqrt (0 0 0) = 0 0 0
197214
inversesqrt (0 0 0) = 0 0 0
215+
cbrt (0 0 0) = 0 0 0
198216
fmod (0 0 0, 0 0 0) = 0 0 0
199217
mod (0 0 0, 0 0 0) = 0 0 0
200218
abs (137) = 137
@@ -209,6 +227,7 @@ Compiled test.osl -> test.oso
209227
sign (101.29) = 1
210228
sqrt (101.29) = 10.0643
211229
inversesqrt (101.29) = 0.0993612
230+
cbrt (101.29) = 4.66146
212231
fmod (101.29, 151.935) = 101.29
213232
fabs (-137.59) = 137.59
214233
floor (-137.59) = -138
@@ -218,6 +237,7 @@ Compiled test.osl -> test.oso
218237
sign (-137.59) = -1
219238
sqrt (-137.59) = 0
220239
inversesqrt (-137.59) = 0
240+
cbrt (-137.59) = -5.16253
221241
mod (16, 7) = 2
222242
fmod (16, 7) = 2
223243
mod (16, 7) = 2
@@ -231,6 +251,7 @@ Compiled test.osl -> test.oso
231251
sign (101.29 101.29 101.29) = 1 1 1
232252
sqrt (101.29 101.29 101.29) = 10.0643 10.0643 10.0643
233253
inversesqrt (101.29 101.29 101.29) = 0.0993612 0.0993612 0.0993612
254+
cbrt (101.29 101.29 101.29) = 4.66146 4.66146 4.66146
234255
fmod (101.29 101.29 101.29, 151.935 151.935 151.935) = 101.29 101.29 101.29
235256
fabs (-137.59 -137.59 -137.59) = 137.59 137.59 137.59
236257
floor (-137.59 -137.59 -137.59) = -138 -138 -138
@@ -240,6 +261,7 @@ Compiled test.osl -> test.oso
240261
sign (-137.59 -137.59 -137.59) = -1 -1 -1
241262
sqrt (-137.59 -137.59 -137.59) = 0 0 0
242263
inversesqrt (-137.59 -137.59 -137.59) = 0 0 0
264+
cbrt (-137.59 -137.59 -137.59) = -5.16253 -5.16253 -5.16253
243265
fmod (-137.59 -137.59 -137.59, -206.385 -206.385 -206.385) = -137.59 -137.59 -137.59
244266
mod (-137.59 -137.59 -137.59, -206.385 -206.385 -206.385) = -137.59 -137.59 -137.59
245267
varying:
@@ -251,6 +273,7 @@ Compiled test.osl -> test.oso
251273
sign (1) = 1
252274
sqrt (1) = 1
253275
inversesqrt (1) = 1
276+
cbrt (1) = 1
254277
fmod (1, 1.5) = 1
255278
mod (1, 1.5) = 1
256279
fabs (1 1 1) = 1 1 1
@@ -261,6 +284,7 @@ Compiled test.osl -> test.oso
261284
sign (1 1 1) = 1 1 1
262285
sqrt (1 1 1) = 1 1 1
263286
inversesqrt (1 1 1) = 1 1 1
287+
cbrt (1 1 1) = 1 1 1
264288
fmod (1 1 1, 1.5 1.5 1.5) = 1 1 1
265289
mod (1 1 1, 1.5 1.5 1.5) = 1 1 1
266290

testsuite/miscmath/test.osl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ test ()
2727
printf (" sign (%g) = %g\n", a, sign(a));
2828
printf (" sqrt (%g) = %g\n", a, sqrt(a));
2929
printf (" inversesqrt (%g) = %g\n", a, inversesqrt(a));
30+
printf (" cbrt (%g) = %g\n", a, cbrt(a));
3031
printf (" fmod (%g, %g) = %g\n", a, b, fmod(a, b));
3132
a = -137.59;
3233
b = 1.5*a;
@@ -38,6 +39,7 @@ test ()
3839
printf (" sign (%g) = %g\n", a, sign(a));
3940
printf (" sqrt (%g) = %g\n", a, sqrt(a));
4041
printf (" inversesqrt (%g) = %g\n", a, inversesqrt(a));
42+
printf (" cbrt (%g) = %g\n", a, cbrt(a));
4143

4244
i = 16;
4345
int j = 7;
@@ -62,6 +64,7 @@ test ()
6264
printf (" sign (%g) = %g\n", a, sign(a));
6365
printf (" sqrt (%g) = %g\n", a, sqrt(a));
6466
printf (" inversesqrt (%g) = %g\n", a, inversesqrt(a));
67+
printf (" cbrt (%g) = %g\n", a, cbrt(a));
6568
printf (" fmod (%g, %g) = %g\n", a, b, fmod(a, b));
6669
a = -137.59;
6770
b = 1.5*a;
@@ -73,6 +76,7 @@ test ()
7376
printf (" sign (%g) = %g\n", a, sign(a));
7477
printf (" sqrt (%g) = %g\n", a, sqrt(a));
7578
printf (" inversesqrt (%g) = %g\n", a, inversesqrt(a));
79+
printf (" cbrt (%g) = %g\n", a, cbrt(a));
7680
printf (" fmod (%g, %g) = %g\n", a, b, fmod(a, b));
7781
printf (" mod (%g, %g) = %g\n", a, b, mod(a, b));
7882
}
@@ -89,6 +93,7 @@ test ()
8993
printf (" sign (%g) = %g\n", a, sign(a));
9094
printf (" sqrt (%g) = %g\n", a, sqrt(a));
9195
printf (" inversesqrt (%g) = %g\n", a, inversesqrt(a));
96+
printf (" cbrt (%g) = %g\n", a, cbrt(a));
9297
printf (" fmod (%g, %g) = %g\n", a, b, fmod(a, b));
9398
printf (" mod (%g, %g) = %g\n", a, b, mod(a, b));
9499
}
@@ -104,6 +109,7 @@ test ()
104109
printf (" sign (%g) = %g\n", a, sign(a));
105110
printf (" sqrt (%g) = %g\n", a, sqrt(a));
106111
printf (" inversesqrt (%g) = %g\n", a, inversesqrt(a));
112+
printf (" cbrt (%g) = %g\n", a, cbrt(a));
107113
printf (" fmod (%g, %g) = %g\n", a, b, fmod(a, b));
108114
printf (" mod (%g, %g) = %g\n", a, b, mod(a, b));
109115
}

0 commit comments

Comments
 (0)