EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: Network Accessable Types
From: "Jeff Hill" <[email protected]>
To: "'Marty Kraimer'" <[email protected]>, <[email protected]>
Date: Wed, 20 Jul 2005 10:44:16 -0600
> The set of well defined types is:

Defining another size locked type space enum is not enough of course. You
will also need to define another set of typedefs with corresponding names.
Or anyways that is the typical approach. This was used for example with the
CA interfaces in R3.13 and R3.14 - i.e. DBR_DOUBLE corresponds to
dbr_double_t. 

However, as I have mentioned before, my experience has been that programmers
become complacent - allowing their applications to become 32 bit
architecture dependent. They use the type code but generally neglect to use
the corresponding typedef - they learn that dbr_double_t is generally always
a C type "double" (on 32 bit systems), and so they just use "double". That's
what I observed with typical CA client applications. Use of interface
designs with "void *" pointers does not allow the compiler to detect such
inconsistencies.

We all know by now that DA takes a different approach. DA knows the C data
type interfaced by the user and range checks / converts accordingly. The DA
design rationale is that the first priority is to know exactly what data
type the user might be actually using so that problems can be detected
during conversion.

At our SLAC meeting I mentioned that I felt that DA was lacking in
capabilities allowing the client application to learn the native type used
in the server for each property. At the recent ANL meeting I showed some
example code demonstrating an upgrade for DA allowing a sophisticated client
to learn the native type (see below for those who were not at the ANL
meeting). An important feature of this design is that there would be three
types of property catalogs; one for read/write access, one for read access,
and one for learning only the native type (in the absence of an instance of
the data). This organization, and some support templates, allows the user to
write the traverse and find functions only once, but use them in all three
of the situations described above (see below).

Most CA client applications in use today use type double for analog values
and assume that the IOC will not produce anything larger. We appear to live
quite comfortably within the range of a 64 bit floating point types. For
practical reasons, my guess is that as 128 bit floats start to be more
commonly available they will be used initially for their improved precision
and not so much for their additional range. I am also guessing that CPUs
supporting 128 bit floats in hardware will be introduced first at the client
side. As 64 bit architectures become commonplace, 32 bit compilers will
probably routinely support software implementations of 128 bit floats
accessed via type "long double". This will allow well written 32 bit clients
to interact predictably with 64 bit servers - they can switch to type "long
double" should the server specify via the network protocol that the native
type is a 128 bit float. On a 64 bit architectures less energetic
programmers will probably eventually use 128 bit floats for all analog
values.

What if the server has a native type that is too large to be expressed as a
C type with the compiler used to compile the client? Telling them that it is
a nadTypeFloat128 isn't going to make that situation better. What *will*
help is to allow them to continue using the largest possible floating point
variable but detect during assignment all numbers that are not expressible
in their choice of variable. Many, if not most of the numbers involved will
not be out of range. Well written clients will respond appropriately when an
out of range indication is received.

What if we would like to write a client application that will use the same
native type as the server? DA interfaced clients have no problems with that
situation because it will be easy to write a DA interfaced component that
traverses the propertyCatalog and creates (in a type differentiated
callback) an instance of a template supplying for the template argument a
type functionally identical (i.e. size locked identical) to the type used in
the server. In languages w/o templates we simply call a different factory
method for each type that is needed from the type differentiated callback.
Templates makes this type of code where the type varies, but the algorithm
doesn't quite easy to write and maintain. Programmers will also probably
quickly arrive at the conclusion that it is only necessary to inflate
templates for the promoted types (as was the conclusion when implementing
the DA support libraries). Promoting to larger types might appear initially
to some to be intrusive, but when one looks at what occurs under the hood in
the compiler it can be discovered that implicit promotion is already quite
commonplace in C and C++ object code.

Finally, despite superior alternatives mentioned in the previous paragraph,
some users will insist on a data type code such as NadType (presumably for
use in a "C" myopic type code indexed jump table or switch statement). A
proliferation of such type code spaces is inevitable. Nevertheless, it will
be trivial to provide DataAccess support library components mapping to any
one of a number of type spaces. Will such support codes be sensitive to
architecture (as decided by the compiler)? You bet. So are all such mappings
such as "dbr_double_t" to "double". However, in practice we discover that
there are not that many mappings. Currently, with 32 bit systems we have
only one (one for each type code space that is).

PropertyId propertyX;
PropertyId propertyY;
PropertyId propertyZ;
PropertyId propertyI;

struct MyContainer 
{
public:
    MyContainer ();
    PropertyManipulator::catalog_t & makeManipulator ();
    PropertyViewer::catalog_t & makeViewer () const;
    static PropertySurveyor::catalog_t & makeSurveyor ();
private:
    int x;
    float y;
    double z;
    char i;
    template < class VIEWER >
    static void traverse ( VIEWER & );
    template < class VIEWER >
    static bool find ( const PropertyId &, VIEWER & );
};

MyContainer::MyContainer () 
{
}

inline PropertyManipulator::catalog_t & MyContainer::makeManipulator ()
{
    return * new ClassCatalog < MyContainer, PropertyManipulator, traverse,
find > ( *this );
}

inline PropertyViewer::catalog_t & MyContainer::makeViewer () const
{
    return * new ClassCatalog < MyContainer, PropertyViewer, traverse, find
> ( *this );
}

inline PropertySurveyor::catalog_t & MyContainer::makeSurveyor ()
{
    return * new ClassCatalog < MyContainer, PropertySurveyor, traverse,
find > ();
}

template < class VIEWER >
inline void MyContainer :: traverse ( VIEWER & viewer )
{
    viewer.reveal ( propertyX, & MyContainer::x );
    viewer.reveal ( propertyY, & MyContainer::y );
    viewer.reveal ( propertyZ, & MyContainer::z );
    viewer.reveal ( propertyI, & MyContainer::i );
}

template < class VIEWER >
inline bool MyContainer::find ( const PropertyId & id, VIEWER & viewer )  
{
    bool status = true;
    if ( id == propertyX ) {
    	viewer.reveal ( propertyX, & MyContainer::x );
    }
    else if ( id == propertyY ) {
    	viewer.reveal ( propertyY, & MyContainer::y );
    }
    else if ( id == propertyZ ) {
    	viewer.reveal ( propertyY, & MyContainer::z );
    }
    else if ( id == propertyI ) {
    	viewer.reveal ( propertyY, & MyContainer::i );
    }
    else {
        status = false;
    }
    return status;
}

void fred ()
{
    MyContainer mc;
    PropertyManipulator::catalog_t & catM = mc.makeManipulator ();
    PropertyViewer::catalog_t & catI = mc.makeViewer ();
    PropertySurveyor::catalog_t & catS = MyContainer::makeSurveyor ();
}


> -----Original Message-----
> From: Marty Kraimer [mailto:[email protected]]
> Sent: Friday, July 15, 2005 6:52 AM
> To: [email protected]
> Subject: Network Accessable Types
> 
> At this week's meeting I think we agreed, except perhaps Jeff, that we
> want to define a set of well defined types for network accessable data.
> 
> These types are used as follows:
> 
> 1) Data that is meant to be network accessable should be composed of
> network accessable data types
> 2) A client should be able to discover the network accessable data types
> of the server's data.
> 
> epicsTypes was an attempt by Andrew and I to define such a set. Perhaps
> using epics in that name made it seem to be a lot more than just network
> accessable data types. The following is a proposed definition for the
> well defined network accessable types that is an extension of what
> epicsTypes defines. The main changes are:
> 
> 1) nad (network accessable data) is used instead of epics.
>      Is this a good name?
>      If not what is a better name?
> 2) It adds
>      a) unsigned types
>      b) property catalog
>      c) time stamp
>      d) map
> 
> The set of well defined types is:
> 
>  enum NadType {
>     nadTypeUnknown,
>     nadTypeBoolean,
>     nadTypeOctet,
>     nadTypeInt16,
>     nadTypeUInt16,
>     nadTypeInt32,
>     nadTypeUInt32,
>     nadTypeInt64,
>     nadTypeUInt64,
>     nadTypeFloat32,
>     nadTypeFloat64,
>     nadTypeString,
>     nadTypeArray,
>     nadTypeMDArray,
>     nadTypePropertyCatalog,
>     // Following are usefull common types
>     nadTypeTimeStamp,
>     nadTypeEnum,
>     nadTypeMap
> };
> 
> Note that a char type is NOT defined because it is extremely difficult
> or impossible to define a network accessable char data type.
> 
> Let me briefly describe these types
> 
> nadTypeUnknown - This is reserved for the case where the type is not
> known. Well behaved sources of data will not present such data.
> 
> nadTypeBoolean - This will have the values false and true and is not
> meant to be converted to any other nadType
> 
> nadTypeOctet - This is an 8 bit byte. It is NOT a numeric data type and
> is not automatically converted to any other type
> 
> nadTypeInt16,...,nadTypeFloat64 - Primitive data types. The unsigned
> types should not be used unless absolutely necessarry. An implementation
> can convert between these types using the rules of the language being
> used. Thus C++ uses it's conversion rules, Java uses it's rules, etc.
> 
> nadTypeString - A UTF-8 encoded character string..
> 
> nadTypeArray - An array. The elements of the array can be any of the
> nadTypes except nadTypeUnknown.
> 
> nadTypeMDArray - A multidimensional array.
>               What types are alowed?
>                Perhaps only nadTypeOctet,...nadTypeFloat64?
> 
> nadTypePropertyCatalog - Is this the correct name or should it be
> Struct? Using PropertyCatalog implys that we are agreeing the dataAccess
> is the way data is transfered between network accessable components.
> 
> nadTypeTimeStamp - This is a "convience" type. It is provided because it
> is so widely used.
> 
> nadTypeEnum - Again this is a convience type.
> 
> nadTypeMap - Convience type. If available, it will be widely used.
> 
> 
> If these types are acceptable, then it will still be necessary to agree
> about the details of each type.
> 
> Marty
> 
> 
> 




Replies:
Re: Network Accessable Types Marty Kraimer
References:
Network Accessable Types Marty Kraimer

Navigate by Date:
Prev: Re: Standard String Andrew Johnson
Next: Re: Standard String Benjamin Franksen
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Network Accessable Types Marty Kraimer
Next: Re: Network Accessable Types Marty Kraimer
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·