In this section we describe the convention we should follow whenever we are coding the test cases. Please follow these rules for each of the different elements when coding. We heavily borrow from LLVM coding standarts and adapt it to our necessities. This document is still under construction and it might change according to our necessities should them be different in the future.
All the tests are organized inside of the /tests
folder. We use an structure that divides the tests into directives, and inside we place all the tests for that given directive. In some cases we do not want to test just a single directive (e.g. /tests/applications
contains whole applications code). For such cases it is possible to introduce new folders, but this will have to get approved before it is done. Our current tests are for OpenMP 4.5. Once we start moving towards other OpenMP specifications, this folder structure might change.
Filenames should all start with test_ follow by the main directive (e.g. or feature tested), follow by other possible directives or clauses that are used and are important for the test, follow by a short description of the test. There should be no spaces in the filename, instead spaces should be replaced by underscores (_). For example, the file test_target_data_if.c
is the source code for a test that uses the target data construct and test the if clause.
All files should contain a header similar to the following header. This header should be located after the // RUN:...
commands. It should contain a description of what the test does, what is the version of OpenMP we are using and which API standard we are using, the name of the file, and a more descriptive title.
#!C
//===-- test_target_data_map.c - test of the map clause in target data ----===//
//
// OpenMP API Version 4.5 Nov 2015
//
// This file is a test for the target data construct when used with the map
// clause. This clause should create the mapping of variables into the device
// and do the data movement or allocation depending on the map type modifier
// from, to, fromto and alloc. This test has a function for each of this type
// modifier. This test uses arrays of size N which values are modified in the
// device and tested in the host. Creation and data movement of the data inside
// the array is according to the used type modifier.
//
//===----------------------------------------------------------------------===//
After the header, all necessary includes should be grouped together. The order of these includes should be:
It is fine to group different includes together by separating them from the first block.
Here is an example:
#!C
#include "applicationInclude.h"
#include <mkl.h>
#include <omp.h>
#include <stdlib>
#include <stdio>
// ...
#!C
#pragma omp target data map(from : h_array_h[0 : N]) \
map(from : h_array_s[0 : N]) \
map(from : isHost)
{
#pragma omp target
{
} //end target
} //end target data
#!C
// Test for OpenMP 4.5 target data map(from: )
int test_map_from() {
}
#!C
int function (int a) {
int a;
int b;
{
int c = a + b;
printf("c = %d\n",c);
}
}
Here is an example:
#!C
int myFunction(int a, int b) {
int c = 3;
int d;
d = myOtherFunc(a, b, c);
if (c > d) {
return a;
} else if (d < a && c == 3) {
printf("here is a test\n");
return a*b + c;
}
return 0;
}
Here we discuss formatting that is OpenMP specific.
The openmp pragma should have no indentation. It should start at the beginning of the line. If the #pragma omp
line is too long, it can be split by using \
at the end of the line and continuing in the following line. in this case, you should leave 8 spaces starting the following lines. This way the new line should align with the previous line start after the #pragma
compiler clause. If you use more than two lines make sure that the \
at the end of the line are aligned
#!C
#pragma omp target data if(size > SIZE_THRESHOLD) map(to: size) \
map(tofrom: c[0:size]) \
map(to: a[0:size], b[0:size], i)
If your clause takes arguments (e.g. map and if). You should leave no space between the clause and the parenthesis. For example: map(...)
or if(...)
.
For example:
#!C
#pragma omp target data map(tofrom: array[0:N], array2, array3[:4])
When possible, please use the OpenMP Header file to output info comments, warnings, and errors. For more information go to The header file information.
#!C
//===-- test_target_data_map.c - test of the map clause in target data ----===//
//
// OpenMP API Version 4.5 Nov 2015
//
// This file is a test for the target data construct when used with the map
// clause. This clause should create the mapping of variables into the device
// and do the data movement or allocation depending on the map type modifier
// from, to, fromto and alloc. This test has a function for each of this type
// modifier. This test uses arrays of size N which values are modified in the
// device and tested in the host. Creation and data movement of the data inside
// the array is according to the used type modifier.
//
//===----------------------------------------------------------------------===//
#include <omp.h>
#include <stdio.h>
// Test for OpenMP 4.5 target data map(from: )
int test_map_from() {
printf("test_map_from\n");
int sum = 0, sum2 = 0, errors = 0, isHost = 0;
// host arrays: heap and stack
int *h_array_h = (int *)malloc(N*sizeof(int));
int h_array_s[N];
#pragma omp target data map(from : h_array_h[0 : N]) \
map(from : h_array_s[0 : N]) \
map(from : isHost)
{
#pragma omp target
{
isHost = omp_is_initial_device();
for (int i = 0; i < N; ++i) {
h_array_h[i] = 1;
h_array_s[i] = 2;
}
} // end target
} // end target data
// checking results
for (int i = 0; i < N; ++i) {
sum += h_array_h[i];
sum2 += h_array_s[i];
}
free(h_array_h);
errors = (N != sum) || (2*N != sum2);
if (!errors)
printf("Test passed on %s\n", (isHost ? "host" : "device"));
else
printf("Test failed on %s: sum=%d, sum2=%d, N=%d\n", (isHost ? "host" : "device"), sum, sum2, N);
return errors;
}