[PD-dev] [PD] more about float limitation

katja katjavetter at gmail.com
Wed Feb 4 10:57:38 CET 2015

This sounds like a very interesting approach, IOhannes. Regarding disk
space it is nowadays no problem at all to store fat binaries, even on
a small device like Raspberry Pi.

To be sure if I understand the idea correctly: the setup method of
each class is renamed (by the build system, essentially), and
precision-aware Pd looks for that new name so it loads the code for
the proper precision. This way you can bundle two versions of a class
(or lib) in a single executable, one for each precision. The setup
method of the wrong precision will not be called by Pd. Am I right?

Does it also mean the rest of the wrong-precision code will not be
loaded? What will happen with unintentionally exported symbols, like
private functions accidentally not declared static, or functions
defined in shared files? Compiler-dependent methods exist to hide
symbols by default. Then, the same approach for renaming class setup
methods according to precision, might be used to explicitly define
them as exported symbol.

What would a legacy Pd build do with fat-precision binaries? Could we
consider single precision the default and not rename the setup
function compiled for single precision so it will still work with
legacy Pd? If the extensions are not modified, a user can't see
whether an external is fat-precision or not.


On Wed, Feb 4, 2015 at 3:40 AM, IOhannes m zmölnig <zmoelnig at iem.at> wrote:
> On 02/03/2015 08:29 PM, IOhannes m zmölnig wrote:
>> On 02/03/2015 08:16 PM, IOhannes m zmölnig wrote:
>>> EXTERN t_class *class_new32(...)
>>> EXTERN t_class *class_new64(...)
>> this btw, would also allow to write externals that provide both single-
>> and double-prevision versions of an objectclass, without the need to
>> change the extension.
> they key to this is to provide dummy registration classes for the
> unsupported precisions, so an external compiled for the "wrong"
> architecture can be loaded by dlopen() but cannot actually *do* anything
> (wrong).
>> it's probably possible to all this in a single wrapper file, but i hope
>> it's easier to understand without preprocessor magic.
> a probably more readable example is the following:
> suppose we have a implementation of a given external (whose author used
> t_float/t_sample throughout, but has not done anything yet to port it to
> a singe/double "phat" binary.
> the objectclass is "mycobject" and lives in mycobject.c
> then the following should be enough to make a phat binary:
> <mycobject_phat.c>
>     void mycobject_setup32();
>     void mycobject_setup64();
>     void mycobject_setup() {
>       mycobject_setup64();
>       mycobject_setup32();
>     }
> <mycobject_phat.c>
> and compile the original code with the above glue as follows:
> $ cc -c -o mycobject-single.o mycobject.c -DPD_FLOATSIZE=32 \
>       -Dmycobject_setup=mycobject_setup32
> $ cc -c -o mycobject-double.o mycobject.c -DPD_FLOATSIZE=64 \
>       -Dmycobject_setup=mycobject_setup64
> $ cc -c -o mycobject-phat.o mycobject-phat.c
> $ cc -o mycobject.pd_linux \
>       mycobject-single.o mycobject-double.o mycobject-phat.o -lc
> so the changes required to build such phat binaries are mainly (only¹)
> in the build-system, and no (properly written) code needs be touched.
> gfmadsr
> IOhannes
> ¹ the glue-code given above is trivial and it should be easy to write a
> reuseable wrapper that is part of the build-system.
> something like embedding the following file in the build-system
> <phat.c>
> #define CONCAT_EXPAND(s1, s2) s1 ## s2
> #define CONCAT(s1,s2) CONCAT_EXPAND(s1,s2)
> void CONCAT(SETUP, 32);
> void CONCAT(SETUP, 64);
> void SETUP () {
>  return 0;
> }
> </phat.c>
> and compiling it as (3rd line in the above example):
> $ cc -c -o mycobject-phat.o phat.c -DSETUP=mycobject_setup
> _______________________________________________
> Pd-dev mailing list
> Pd-dev at lists.iem.at
> http://lists.puredata.info/listinfo/pd-dev

More information about the Pd-dev mailing list