| [0b990d] | 1 |  | 
|---|
|  | 2 | /** \page develop Developing Code Using SC | 
|---|
|  | 3 |  | 
|---|
|  | 4 | In addition to the executables, the Scientific Computing toolkit libraries | 
|---|
|  | 5 | and include files can be installed on your machine.  This is described in | 
|---|
|  | 6 | the \ref compile section of this manual. | 
|---|
|  | 7 |  | 
|---|
|  | 8 | The <tt>sc-config</tt> program can be use to obtain the compilers, compiler | 
|---|
|  | 9 | options, and libraries needed to use the SC toolkit from your program. | 
|---|
|  | 10 | This utility is discussed below, along with how the SC toolkit must be | 
|---|
|  | 11 | initialized in your <tt>main</tt> subroutine. | 
|---|
|  | 12 |  | 
|---|
|  | 13 | <ul> | 
|---|
|  | 14 | <li> \ref scconfig | 
|---|
|  | 15 | <li> \ref scinit | 
|---|
|  | 16 | <li> \ref devsamp | 
|---|
|  | 17 | <li> \ref scexcept | 
|---|
|  | 18 | <li> \ref devcheck | 
|---|
|  | 19 | </ul> | 
|---|
|  | 20 |  | 
|---|
|  | 21 | \section scconfig The sc-config Program | 
|---|
|  | 22 |  | 
|---|
|  | 23 | The sc-config program returns information about how SC was compiled | 
|---|
|  | 24 | and installed.  See \ref sc-config for more information. | 
|---|
|  | 25 |  | 
|---|
|  | 26 | \section scinit Initializing SC | 
|---|
|  | 27 |  | 
|---|
|  | 28 | First the execution environment must be initialized using | 
|---|
|  | 29 | the ExEnv init member. | 
|---|
|  | 30 |  | 
|---|
|  | 31 | <pre> | 
|---|
|  | 32 | ExEnv::init(argc, argv); | 
|---|
|  | 33 | </pre> | 
|---|
|  | 34 |  | 
|---|
|  | 35 | By default, all output will go to the console stream, cout.  To change | 
|---|
|  | 36 | this, use the following code: | 
|---|
|  | 37 |  | 
|---|
|  | 38 | <pre> | 
|---|
|  | 39 | ostream *outstream = new ofstream(outputfilename); | 
|---|
|  | 40 | ExEnv::set_out(outstream); | 
|---|
|  | 41 | </pre> | 
|---|
|  | 42 |  | 
|---|
|  | 43 | MPI is allowed wait until MPI_Init is called to fill in argc and argv, so | 
|---|
|  | 44 | you may have to call MPI_Init before you even know that we ready to | 
|---|
|  | 45 | construct MPIMessageGrp.  So if an MPIMessageGrp is needed, it is up to the | 
|---|
|  | 46 | developer to call MPI_Init to get the argument list for certain MPI | 
|---|
|  | 47 | implementations. | 
|---|
|  | 48 |  | 
|---|
|  | 49 | <pre> | 
|---|
|  | 50 | MPI_Init(&argc, &argv); | 
|---|
|  | 51 | </pre> | 
|---|
|  | 52 |  | 
|---|
|  | 53 | When files are read and written, an extension is added to a | 
|---|
|  | 54 | basename to construct the file name.  The default is "SC". | 
|---|
|  | 55 | To use another basename, make the following call, where | 
|---|
|  | 56 | <tt>basename</tt> is a <tt>const char *</tt>: | 
|---|
|  | 57 |  | 
|---|
|  | 58 | <pre> | 
|---|
|  | 59 | SCFormIO::set_default_basename(basename); | 
|---|
|  | 60 | </pre> | 
|---|
|  | 61 |  | 
|---|
|  | 62 | If your job might run in parallel, then make the following | 
|---|
|  | 63 | call or the nodes will print redundant information.  The | 
|---|
|  | 64 | <tt>myproc</tt> argument is the rank of the called node. | 
|---|
|  | 65 |  | 
|---|
|  | 66 | <pre> | 
|---|
|  | 67 | SCFormIO::init_mp(myproc); | 
|---|
|  | 68 | </pre> | 
|---|
|  | 69 |  | 
|---|
|  | 70 | This segment of code sets up an object to provide multi-threading: | 
|---|
|  | 71 |  | 
|---|
|  | 72 | <pre> | 
|---|
|  | 73 | RefThreadGrp thread = ThreadGrp::initial_threadgrp(argc, argv); | 
|---|
|  | 74 | ThreadGrp::set_default_threadgrp(thread); | 
|---|
|  | 75 | if (thread.nonnull()) | 
|---|
|  | 76 | ThreadGrp::set_default_threadgrp(thread); | 
|---|
|  | 77 | else | 
|---|
|  | 78 | thread = ThreadGrp::get_default_threadgrp(); | 
|---|
|  | 79 | </pre> | 
|---|
|  | 80 |  | 
|---|
|  | 81 | This segment of code sets up the message passing object: | 
|---|
|  | 82 |  | 
|---|
|  | 83 | <pre> | 
|---|
|  | 84 | RefMessageGrp grp = MessageGrp::initial_messagegrp(argc, argv); | 
|---|
|  | 85 | if (grp.nonnull()) | 
|---|
|  | 86 | MessageGrp::set_default_messagegrp(grp); | 
|---|
|  | 87 | else | 
|---|
|  | 88 | grp = MessageGrp::get_default_messagegrp(); | 
|---|
|  | 89 | </pre> | 
|---|
|  | 90 |  | 
|---|
|  | 91 | \section devsamp MP2 Implementation Example | 
|---|
|  | 92 |  | 
|---|
|  | 93 | This section illustrates how to add a new method a new method to MPQC. | 
|---|
|  | 94 |  | 
|---|
|  | 95 | \subsection devsampsrc MP2 Implementation Example: Source | 
|---|
|  | 96 |  | 
|---|
|  | 97 | This example code illustrates a complete MP2 energy | 
|---|
|  | 98 | implementation using the SC Toolkit.  First an MP2 class is | 
|---|
|  | 99 | declared and the necesary base class member functions are | 
|---|
|  | 100 | provided.  Next a ClassDesc is defined.  Finally, the member | 
|---|
|  | 101 | functions are defined. | 
|---|
|  | 102 |  | 
|---|
|  | 103 | Note that no main routine is provided.  This is because this file | 
|---|
|  | 104 | is designed to be used to extend the functionality of the mpqc | 
|---|
|  | 105 | executable.  To generate a new mpqc executable with the new class | 
|---|
|  | 106 | available for use, see the \ref devsampmak section. | 
|---|
|  | 107 |  | 
|---|
|  | 108 | \include mp2.cc | 
|---|
|  | 109 |  | 
|---|
|  | 110 | \subsection devsampmak MP2 Implementation Example: Makefile | 
|---|
|  | 111 |  | 
|---|
|  | 112 | This example Makefile demonstrates how to link in a new class to | 
|---|
|  | 113 | form a new mpqc executable, here named mp2.  The code is given in | 
|---|
|  | 114 | the \ref devsampsrc section.  The \ref scconfig "sc-config command" | 
|---|
|  | 115 | is used to obtain information about how the SC toolkit | 
|---|
|  | 116 | was compiled and installed.  The library specified with -lmpqc | 
|---|
|  | 117 | provides the main routine from mpqc. | 
|---|
|  | 118 |  | 
|---|
|  | 119 | \include Makefile | 
|---|
|  | 120 |  | 
|---|
|  | 121 | \subsection devsampinp MP2 Implementation Example: Input | 
|---|
|  | 122 |  | 
|---|
|  | 123 | This input file can be used with the program illustrated in | 
|---|
|  | 124 | the \ref devsampsrc section.  It will compute the MP2 energy | 
|---|
|  | 125 | using the new MP2 class.  Note that only the | 
|---|
|  | 126 | \ref mpqcoo "object-oriented input format" can be used with | 
|---|
|  | 127 | user provided classes. | 
|---|
|  | 128 |  | 
|---|
|  | 129 | \include mp2.in | 
|---|
|  | 130 |  | 
|---|
|  | 131 | \section scexcept Exception Handling in SC | 
|---|
|  | 132 |  | 
|---|
|  | 133 | The development of SC began before exception handling was available in C++. | 
|---|
|  | 134 | A retrofit of the code to use exceptions is in progress.  It is difficult | 
|---|
|  | 135 | to retrofit a code, especially a parallel code, to do exception handling. | 
|---|
|  | 136 | There will be some limitations: exception handling will not work well for | 
|---|
|  | 137 | parallel jobs, objects whose members throw might be left in a questionable | 
|---|
|  | 138 | state, etc.  However, it is intended that SC objects will be usable in an | 
|---|
|  | 139 | interactive environment.  It is also planned that exceptions be used | 
|---|
|  | 140 | internally to facilitate recover from certain problems. | 
|---|
|  | 141 |  | 
|---|
|  | 142 | All new code should use exceptions instead of exit or abort and allocate | 
|---|
|  | 143 | resources in such a way that, if an exception occurs, all resources such as | 
|---|
|  | 144 | memory or locks are released.  A hierarchy of exception classes has been | 
|---|
|  | 145 | created that maps better to scientific computing than the standard | 
|---|
|  | 146 | exceptions.  More information is below, as well as in the documentation for | 
|---|
|  | 147 | the SCException class and its derivatives. | 
|---|
|  | 148 |  | 
|---|
|  | 149 | <ul> | 
|---|
|  | 150 | <li> \ref scexceptmem | 
|---|
|  | 151 | <li> \ref scexceptlocks | 
|---|
|  | 152 | <li> \ref scexcepttimer | 
|---|
|  | 153 | <li> \ref scexceptexample | 
|---|
|  | 154 | <li> \ref scexceptdebug | 
|---|
|  | 155 | </ul> | 
|---|
|  | 156 |  | 
|---|
|  | 157 | \subsection scexceptmem Exceptions and Memory Allocation | 
|---|
|  | 158 |  | 
|---|
|  | 159 | Consider the following code fragment: | 
|---|
|  | 160 |  | 
|---|
|  | 161 | <pre> | 
|---|
|  | 162 | Object *obj = new Object; | 
|---|
|  | 163 | double *array = new double[n]; | 
|---|
|  | 164 |  | 
|---|
|  | 165 | f(obj, array, mol); | 
|---|
|  | 166 |  | 
|---|
|  | 167 | delete obj; | 
|---|
|  | 168 | delete[] array; | 
|---|
|  | 169 | </pre> | 
|---|
|  | 170 |  | 
|---|
|  | 171 | If an exception is thrown in the function f(), then storage for array and | 
|---|
|  | 172 | obj will not be released.  The standard C++ library provides a class, | 
|---|
|  | 173 | auto_ptr, to deal with obj, and the SC toolkit provides a class, auto_vec, | 
|---|
|  | 174 | to deal with array. | 
|---|
|  | 175 |  | 
|---|
|  | 176 | The include files for these two classes are: | 
|---|
|  | 177 |  | 
|---|
|  | 178 | <pre> | 
|---|
|  | 179 | #include \<memory\> | 
|---|
|  | 180 | #include \<util/misc/autovec.h\> | 
|---|
|  | 181 | </pre> | 
|---|
|  | 182 |  | 
|---|
|  | 183 | the code would be modified as follows: | 
|---|
|  | 184 |  | 
|---|
|  | 185 | <pre> | 
|---|
|  | 186 | std::auto_ptr<Object> obj(new Object); | 
|---|
|  | 187 | sc::auto_vec<double> array(new double[n]); | 
|---|
|  | 188 |  | 
|---|
|  | 189 | f(obj.get(), array.get()); | 
|---|
|  | 190 |  | 
|---|
|  | 191 | obj.release();  // or just let the destructor release it | 
|---|
|  | 192 | array.release();  // or just let the destructor release it | 
|---|
|  | 193 | </pre> | 
|---|
|  | 194 |  | 
|---|
|  | 195 | Note that when sc::Ref is used to store pointers, the storage will | 
|---|
|  | 196 | automatically be released when necessary.  No special treatment is needed | 
|---|
|  | 197 | to deal with exceptions. | 
|---|
|  | 198 |  | 
|---|
|  | 199 | \subsection scexceptlocks Exceptions and Locks | 
|---|
|  | 200 |  | 
|---|
|  | 201 | Consider the following code fragment: | 
|---|
|  | 202 |  | 
|---|
|  | 203 | <pre> | 
|---|
|  | 204 | g(const sc::Ref<sc::ThreadLock> &lock) | 
|---|
|  | 205 | { | 
|---|
|  | 206 | lock->lock(); | 
|---|
|  | 207 | f(); | 
|---|
|  | 208 | lock->unlock(); | 
|---|
|  | 209 | } | 
|---|
|  | 210 | </pre> | 
|---|
|  | 211 |  | 
|---|
|  | 212 | If f() throws, then the lock is never released.  The ThreadLock | 
|---|
|  | 213 | lock() and unlock() members should not be used anymore.  Now | 
|---|
|  | 214 | do the following: | 
|---|
|  | 215 |  | 
|---|
|  | 216 | <pre> | 
|---|
|  | 217 | g(const sc::Ref<sc::ThreadLock> &lock) | 
|---|
|  | 218 | { | 
|---|
|  | 219 | sc::ThreadLockHolder lockholder(lock); | 
|---|
|  | 220 | f(); | 
|---|
|  | 221 | lockholder->unlock(); // or let the destructor unlock it | 
|---|
|  | 222 | } | 
|---|
|  | 223 | </pre> | 
|---|
|  | 224 |  | 
|---|
|  | 225 | \subsection scexcepttimer Exceptions and Region Timers | 
|---|
|  | 226 |  | 
|---|
|  | 227 | Consider the following code fragment: | 
|---|
|  | 228 |  | 
|---|
|  | 229 | <pre> | 
|---|
|  | 230 | g(const sc::Ref<sc::RegionTimer> ®tim) | 
|---|
|  | 231 | { | 
|---|
|  | 232 | regtim->enter("f()"); | 
|---|
|  | 233 | f(); | 
|---|
|  | 234 | regtim->exit(); | 
|---|
|  | 235 | } | 
|---|
|  | 236 | </pre> | 
|---|
|  | 237 |  | 
|---|
|  | 238 | If f() throws, then the "f()" timing region is never exited. | 
|---|
|  | 239 | Instead use the following: | 
|---|
|  | 240 |  | 
|---|
|  | 241 | <pre> | 
|---|
|  | 242 | g(const sc::Ref<sc::RegionTimer> ®tim) | 
|---|
|  | 243 | { | 
|---|
|  | 244 | sc::Timer timer(regtim, "f()"); | 
|---|
|  | 245 | f(); | 
|---|
|  | 246 | timer.reset(); // or let the destructor exit the region | 
|---|
|  | 247 | } | 
|---|
|  | 248 | </pre> | 
|---|
|  | 249 |  | 
|---|
|  | 250 | \subsection scexceptexample Using the SC Exception Classes | 
|---|
|  | 251 |  | 
|---|
|  | 252 | The SC exceptions provide information that can be used into two | 
|---|
|  | 253 | ways. First, text information is provided so that if the exception is not | 
|---|
|  | 254 | caught at a lower level, then the mpqc executable will catch it and write | 
|---|
|  | 255 | information about the problem to the terminal or an output file.  Second, | 
|---|
|  | 256 | information about the nature of the problem is provided, to permit | 
|---|
|  | 257 | developers to catch the exception and deal with it in some way.  The | 
|---|
|  | 258 | documentation for sc::SCException and all of its derivatives gives more | 
|---|
|  | 259 | information about the exceptions that are available.  As an example, | 
|---|
|  | 260 | consider the following loop, where a maximum number of iterations is | 
|---|
|  | 261 | permitted: | 
|---|
|  | 262 |  | 
|---|
|  | 263 | <pre> | 
|---|
|  | 264 | XYZ::update() | 
|---|
|  | 265 | { | 
|---|
|  | 266 | for (int i=0; i<maxiter; i++) { | 
|---|
|  | 267 | // ... compute xyz update ... | 
|---|
|  | 268 | if (residual < threshold) return; | 
|---|
|  | 269 | } | 
|---|
|  | 270 | throw MaxIterExceeded("too many iterations xyz computation", | 
|---|
|  | 271 | __FILE__, __LINE__, maxiter, class_desc()); | 
|---|
|  | 272 | } | 
|---|
|  | 273 | </pre> | 
|---|
|  | 274 |  | 
|---|
|  | 275 | The first argument to the exception class is a brief description of the | 
|---|
|  | 276 | error.  Additional information can be provided, | 
|---|
|  | 277 | see SCException::elaborate() description below. | 
|---|
|  | 278 | The next two arguments are | 
|---|
|  | 279 | the filename and line number.  The C preprocessor provides these for you | 
|---|
|  | 280 | with the __FILE__ and __LINE__ macros.  The next argument is specific to | 
|---|
|  | 281 | the MaxIterExceeded exception; it is the maximum number of iterations. | 
|---|
|  | 282 | Finally, a ClassDesc* can be given, which will be used to print out the | 
|---|
|  | 283 | class name of the object that failed.  All of these arguments are optional; | 
|---|
|  | 284 | however, the first three should always be given. | 
|---|
|  | 285 |  | 
|---|
|  | 286 | It is possible to provide additional information using the | 
|---|
|  | 287 | SCException::elaborate() member.  This will return a ostream, and the | 
|---|
|  | 288 | additional information can be written to this stream.  However, if for some | 
|---|
|  | 289 | reason it is not possible to write to this stream (say, there wasn't enough | 
|---|
|  | 290 | memory to allocate it), then an exception will be thrown.  For this reason, | 
|---|
|  | 291 | the string description given as the first argument should be informative | 
|---|
|  | 292 | since the additional information might not be available, and attempts to | 
|---|
|  | 293 | use elaborate() should be in a try block.  So, for example, the elaborate() | 
|---|
|  | 294 | member could be used in the above example as follows: | 
|---|
|  | 295 |  | 
|---|
|  | 296 | <pre> | 
|---|
|  | 297 | XYZ::update() | 
|---|
|  | 298 | { | 
|---|
|  | 299 | for (int i=0; i<maxiter; i++) { | 
|---|
|  | 300 | // ... compute xyz update ... | 
|---|
|  | 301 | if (residual < threshold) return; | 
|---|
|  | 302 | } | 
|---|
|  | 303 | MaxIterExceeded ex("too many iterations in xyz computation", | 
|---|
|  | 304 | __FILE__, __LINE__, maxiter, class_desc()); | 
|---|
|  | 305 | try { | 
|---|
|  | 306 | ex.elaborate() << "this can happen when the stepsize is too small" | 
|---|
|  | 307 | << std::endl | 
|---|
|  | 308 | << "the stepsize is " << stepsize | 
|---|
|  | 309 | << std::endl; | 
|---|
|  | 310 | } | 
|---|
|  | 311 | catch (...) {} | 
|---|
|  | 312 | throw ex; | 
|---|
|  | 313 | } | 
|---|
|  | 314 | </pre> | 
|---|
|  | 315 |  | 
|---|
|  | 316 | Note that writing to stream returned by elaborate() won't necessarily cause | 
|---|
|  | 317 | anything to get written to the terminal or an output file.  The information | 
|---|
|  | 318 | will be available when the what() member is called, if writing to the | 
|---|
|  | 319 | stream succeeds.  If the exception is caught by the mpqc main routine, then | 
|---|
|  | 320 | it will be printed for the user to see.  If the program catches the | 
|---|
|  | 321 | exception and determines that it is possible to proceed in a different way, | 
|---|
|  | 322 | then the user will never see the text. | 
|---|
|  | 323 |  | 
|---|
|  | 324 | \subsection scexceptdebug Debugging Code with Exceptions | 
|---|
|  | 325 |  | 
|---|
|  | 326 | Usually, exceptions are not the desired behaviour in a program, and it is | 
|---|
|  | 327 | necessary to debug a program that throws an exception.  This was easy when | 
|---|
|  | 328 | abort was called, because abort would raise a signal that was caught by the | 
|---|
|  | 329 | debugger and the code is stopped at the appropriate place.  With exceptions | 
|---|
|  | 330 | the matter is more complex, because the stack is unwound when an exception | 
|---|
|  | 331 | is thrown and most debugging information is lost.  To work around this | 
|---|
|  | 332 | problem, a breakpoint can be set in code that will be reached only in an | 
|---|
|  | 333 | exception, and will be run before the stack unwind begins.  A useful place | 
|---|
|  | 334 | to do this when GCC is used as the compiler is in the routine | 
|---|
|  | 335 | __cxa_allocate_exception().  So, in gdb, the following could be done: | 
|---|
|  | 336 |  | 
|---|
|  | 337 | <pre> | 
|---|
|  | 338 | $ gdb ./scextest | 
|---|
|  | 339 | (gdb) b main | 
|---|
|  | 340 | (gdb) run | 
|---|
|  | 341 | Breakpoint 1, main () at /home/cljanss/src/SC/src/lib/util/misc/scextest.cc:172 | 
|---|
|  | 342 | 172           f(); | 
|---|
|  | 343 | (gdb) b __cxa_allocate_exception | 
|---|
|  | 344 | (gdb) cont | 
|---|
|  | 345 | Breakpoint 2, 0x40582d46 in __cxa_allocate_exception () | 
|---|
|  | 346 | from /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.5/libstdc++.so.5 | 
|---|
|  | 347 | (gdb) where | 
|---|
|  | 348 | #0  0x40582d46 in __cxa_allocate_exception () | 
|---|
|  | 349 | from /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.5/libstdc++.so.5 | 
|---|
|  | 350 | #1  0x0804b3f7 in f () at /home/cljanss/src/SC/src/lib/util/misc/scextest.cc:60 | 
|---|
|  | 351 | #2  0x0804b9e9 in main () | 
|---|
|  | 352 | at /home/cljanss/src/SC/src/lib/util/misc/scextest.cc:172 | 
|---|
|  | 353 | </pre> | 
|---|
|  | 354 |  | 
|---|
|  | 355 | Giving gdb "b main" followed by "run" was required before gdb could find the | 
|---|
|  | 356 | __cxa_allocate_exception symbol. | 
|---|
|  | 357 |  | 
|---|
|  | 358 | \section devcheck Adding Test Cases to the Verification Suite | 
|---|
|  | 359 |  | 
|---|
|  | 360 | There are two ways to test an MPQC build.  The <tt>testbuild</tt> and | 
|---|
|  | 361 | <tt>testrun</tt> make targets can be used to run test programs in | 
|---|
|  | 362 | various library directories, and the <tt>check</tt> and related make | 
|---|
|  | 363 | targets can be used to run MPQC on sets of input files.  See | 
|---|
|  | 364 | \ref mpqcval for more information about how to run the tests. | 
|---|
|  | 365 |  | 
|---|
|  | 366 | Test programs can be added to the library directories by providing a source | 
|---|
|  | 367 | file with a main routine.  The set of test programs that is to be built and | 
|---|
|  | 368 | run by <tt>testbuild</tt> and <tt>testrun</tt>, respectively, is given by | 
|---|
|  | 369 | the <tt>TESTPROGS</tt> variable in the library's <tt>Makefile</tt>.  It may | 
|---|
|  | 370 | be necessary for an explicit rule to be given for building the test program | 
|---|
|  | 371 | to ensure that necessary libraries are linked in.  If a file named after | 
|---|
|  | 372 | the test program with a <tt>.out</tt> suffix is found in the source | 
|---|
|  | 373 | directory, then <tt>testrun</tt> fail if the command's output differs from | 
|---|
|  | 374 | that file.  Care must be taken to ensure that the output is architecture | 
|---|
|  | 375 | independent in this case.  Otherwise, <tt>testrun</tt> will fail only if | 
|---|
|  | 376 | running the command results in a nonzero return code. | 
|---|
|  | 377 |  | 
|---|
|  | 378 | Additional MPQC test inputs can be added in the | 
|---|
|  | 379 | <tt>src/bin/mpqc/validate</tt> directory.  These inputs can be provided in | 
|---|
|  | 380 | one of two ways.  An input which is used to automatically generate multiple | 
|---|
|  | 381 | test cases can be written (with a <tt>.qci</tt> suffix), or a subdirectory | 
|---|
|  | 382 | with each input can be made.  See <tt>Makefile</tt>, <tt>basis1.qci</tt>, | 
|---|
|  | 383 | and <tt>input</tt> in the <tt>src/bin/mpqc/validate</tt> directory for | 
|---|
|  | 384 | examples. | 
|---|
|  | 385 |  | 
|---|
|  | 386 | After you have added new inputs and modified the Makefile, change into the | 
|---|
|  | 387 | <tt>src/bin/mpqc/validate</tt> subdirectory of your object directory (where | 
|---|
|  | 388 | you compiled MPQC) and type <tt>make inputs</tt>.  This will create a | 
|---|
|  | 389 | <tt>input</tt> subdirectory containing MPQC input files with a | 
|---|
|  | 390 | <tt>.in</tt> suffix.  Files ending with a <tt>.qci</tt> suffix will also be | 
|---|
|  | 391 | placed in the <tt>input</tt> directory.  These contain a description of the | 
|---|
|  | 392 | calculation that is used by the utility program that checks the results of | 
|---|
|  | 393 | the validation suite.  Both the <tt>.in</tt> and <tt>.qci</tt> files for the | 
|---|
|  | 394 | new test cases must be copied into the <tt>ref</tt> directory in the source | 
|---|
|  | 395 | tree.  Note that inputs that are not useful in your build environment are | 
|---|
|  | 396 | not created by <tt>make inputs</tt>. | 
|---|
|  | 397 |  | 
|---|
|  | 398 | */ | 
|---|