OpenCLSort.h 5.34 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
#ifndef __OPENMM_OPENCLSORT_H__
#define __OPENMM_OPENCLSORT_H__

/* -------------------------------------------------------------------------- *
 *                                   OpenMM                                   *
 * -------------------------------------------------------------------------- *
 * This is part of the OpenMM molecular simulation toolkit originating from   *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
12
 * Portions copyright (c) 2010-2025 Stanford University and the Authors.      *
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * This program is free software: you can redistribute it and/or modify       *
 * it under the terms of the GNU Lesser General Public License as published   *
 * by the Free Software Foundation, either version 3 of the License, or       *
 * (at your option) any later version.                                        *
 *                                                                            *
 * This program is distributed in the hope that it will be useful,            *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 * GNU Lesser General Public License for more details.                        *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
 * -------------------------------------------------------------------------- */

#include "OpenCLArray.h"
peastman's avatar
peastman committed
31
#include "OpenCLContext.h"
32
#include "openmm/common/ComputeSort.h"
33
#include "openmm/common/windowsExportCommon.h"
34
35
36
37
38
39

namespace OpenMM {

/**
 * This class sorts arrays of values.  It supports any type of values, not just scalars,
 * so long as an appropriate sorting key can be defined by which to sort them.
40
 * 
41
 * The sorting behavior is specified by a "trait" class that defines the type of data to
42
43
44
 * sort and the key for sorting it.  Here is an example of a trait class for
 * sorting floats:
 * 
45
 * class FloatTrait : public ComputeSortImpl::SortTrait {
46
47
48
49
50
51
52
53
 *     int getDataSize() const {return 4;}
 *     int getKeySize() const {return 4;}
 *     const char* getDataType() const {return "float";}
 *     const char* getKeyType() const {return "float";}
 *     const char* getMinKey() const {return "-MAXFLOAT";}
 *     const char* getMaxKey() const {return "MAXFLOAT";}
 *     const char* getMaxValue() const {return "MAXFLOAT";}
 *     const char* getSortKey() const {return "value";}
54
 * };
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 *
 * The algorithm used is a bucket sort, followed by a bitonic sort within each bucket
 * (in local memory when possible, in global memory otherwise).  This is similar to
 * the algorithm described in
 *
 * Shifu Chen, Jing Qin, Yongming Xie, Junping Zhao, and Pheng-Ann Heng.  "An Efficient
 * Sorting Algorithm with CUDA"  Journal of the Chinese Institute of Engineers, 32(7),
 * pp. 915-921 (2009)
 *
 * but with many modifications and simplifications.  In particular, this algorithm
 * involves much less communication between host and device, which is critical to get
 * good performance with the array sizes we typically work with (10,000 to 100,000
 * elements).
 */
69
    
70
class OPENMM_EXPORT_COMMON OpenCLSort : public ComputeSortImpl {
71
72
73
74
75
public:
    /**
     * Create an OpenCLSort object for sorting data of a particular type.
     *
     * @param context    the context in which to perform calculations
76
77
78
     * @param trait      a SortTrait defining the type of data to sort.  It should have been allocated
     *                   on the heap with the "new" operator.  This object takes over ownership of it,
     *                   and deletes it when the OpenCLSort is deleted.
79
     * @param length     the length of the arrays this object will be used to sort
80
81
82
83
     * @param uniform    whether the input data is expected to follow a uniform or nonuniform
     *                   distribution.  This argument is used only as a hint.  It allows parts
     *                   of the algorithm to be tuned for faster performance on the expected
     *                   distribution.
84
     */
85
    OpenCLSort(OpenCLContext& context, ComputeSortImpl::SortTrait* trait, unsigned int length, bool uniform=true);
86
    ~OpenCLSort();
87
88
89
    /**
     * Sort an array.
     */
90
    void sort(ArrayInterface& data);
91
92
private:
    OpenCLContext& context;
93
    ComputeSortImpl::SortTrait* trait;
peastman's avatar
peastman committed
94
95
96
97
98
    OpenCLArray dataRange;
    OpenCLArray bucketOfElement;
    OpenCLArray offsetInBucket;
    OpenCLArray bucketOffset;
    OpenCLArray buckets;
peastman's avatar
peastman committed
99
    cl::Kernel shortListKernel, shortList2Kernel, computeRangeKernel, assignElementsKernel, computeBucketPositionsKernel, copyToBucketsKernel, sortBucketsKernel;
100
    unsigned int dataLength, rangeKernelSize, positionsKernelSize, sortKernelSize;
101
    bool isShortList, useShortList2, uniform;
102
103
};

104
105
} // namespace OpenMM

106
#endif // __OPENMM_OPENCLSORT_H__