| 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 | */
 | 
|---|