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