From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 1094ba,690ce1f62160d05a X-Google-Attributes: gid1094ba,public X-Google-Thread: 109fba,690ce1f62160d05a X-Google-Attributes: gid109fba,public X-Google-Thread: 1014db,690ce1f62160d05a X-Google-Attributes: gid1014db,public X-Google-Thread: 103376,690ce1f62160d05a X-Google-Attributes: gid103376,public From: "E. Robert Tisdale" Subject: Re: How to Design an Application Programmers' Interface (API) Date: 2000/08/11 Message-ID: <399386EF.4F2AA3E6@netwood.net> X-Deja-AN: 657050777 Content-Transfer-Encoding: 7bit References: <39921178.819F6DCB@netwood.net> X-Accept-Language: en Content-Type: text/plain; charset=us-ascii X-Complaints-To: newsabuse@supernews.com Organization: Posted via Supernews, http://www.supernews.com MIME-Version: 1.0 Newsgroups: comp.lang.c++,comp.lang.c,comp.lang.fortran,comp.lang.ada Date: 2000-08-11T00:00:00+00:00 List-Id: A good API makes it easier for application programmers to write safe and reliable high performance application programs clearly and concisely so that they are easier to read, understand and maintain. It permits library developers and application programmers to work independently of each other and reduces the time required to develop, debug and test applications. An API is a contract between library developers and application programmers. It liberates library developers to implement the API as they see fit by concealing the actual data representation and algorithm implementation but it must also provide application programmers with all the functionality required to manipulate the ADT so that they are not obliged to reach around the API and access the actual data representation directly. The trick is to do all this without imposing any abstraction penalty especially if the abstraction doesn't yield any tangible benefit. I know numerical library API designs best so I will use them as examples. There are lots of really good numerical library API designs but they aren't always as instructive as really poor API designs. The BLAS library API http://www.netlib.org/blas/ was designed to help numerical library developers implement high performance linear algebra packages and wasn't really meant to be used by application programmers.* It supports strided real and complex multidimensional views of one dimensional arrays of real numbers which are useful in many more applications than linear algebra but no other functionality is specified. Part of the problem with the BLAS library API can be traced back to the original Fortran 77 implementation. Fortran 77 isn't very friendly to API designers. It doesn't provide any mechanisms to define new data types or even to define synonyms for existing data types and it doesn't provide any effective mechanism to hide the actual data representation. Abstraction is supported only through the self discipline of cooperative application programmers. The only practical place to construct vector and matrix view objects in a Fortran 77 program is in the argument list of subroutine calls. The result is long argument lists as in SUBROUTINE DGEMM( $ TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC) * .. Scalar Arguments .. CHARACTER*1 TRANSA, TRANSB INTEGER M, N, K, LDA, LDB, LDC DOUBLE PRECISION ALPHA, BETA * .. Array Arguments .. DOUBLE PRECISION A(LDA, *), B(LDB, *), C(LDC, *) which computes C <-- alpha*AB + beta*C from an m by k matrix A, a k by n matrix B and an m by n matrix C. These long argument lists are as hard to write as they are to read and they are expensive to pass to the BLAS library. BLAS matrix view objects are restricted to unit stride within any column and positive stride (leading dimension) within any row greater than the extent of any column. Fortran 77 is, again, mostly responsible for the restriction to unit stride. Numerical algorithms that operate on matrix views generally work best with unit stride between the elements of a column (or row) but it isn't practical for the BLAS library to examine the strides and condense matrix views with arbitrary stride into a temporary matrix with unit stride because there is no way to allocate the required array storage dynamically in Fortran 77. There are about 150 subroutines altogether in the BLAS library for both single and double precision real and complex numbers. There should have been many more subroutines but BLAS library developers complained so some functionality was dropped but some functionality was preserved by passing extra options to the remaining subroutines. This means that instead of resolving functionality in the subroutine name space at compile time, it must be resolved at run time by testing options passed in the argument list. This extra overhead is negligible for operations on large vector and matrix objects but virtually precludes their use on small objects in tight loops. These compromises in the design and specification of the BLAS library API result in too many arbitrary rules and exceptions that are difficult for application programmers to learn and remember and provide too many opportunities to make programming errors which are difficult to detect and debug. Unfortunately, the C, C++ and Fortran 90 language bindings don't improve the BLAS library API very much. They are basically very thin interfaces for the Fortran 77 implementation and don't really support any of the functionality missing from the original Fortran 77 implementation. So what went wrong with the BLAS library API design process? Well, first of all, the BLAS library API designers probably never did precisely identify the ADT that they wanted to support. Second, they never realized the advantage of specifying functionality that they couldn't compel BLAS library developers to support. Third, they couldn't anticipate the advantages of specifying abstraction that Fortran 77 couldn't support. Fourth, by the time the got around to specifying other language bindings, they had already forgotten about basic design principles. * The C++ Matrix Template Library (MTL) http://www.lsc.nd.edu/research/mtl/ was also designed to help library developers implement high performance numerical algorithms in C++ and really isn't useful to application programmers.