aboutsummaryrefslogtreecommitdiff
path: root/cutlass-example
diff options
context:
space:
mode:
Diffstat (limited to 'cutlass-example')
-rw-r--r--cutlass-example/Makefile46
-rw-r--r--cutlass-example/command_line.h254
-rw-r--r--cutlass-example/config_fermi_islip.icnt70
-rw-r--r--cutlass-example/cutlass/convert.h102
-rw-r--r--cutlass-example/cutlass/coord.h287
-rw-r--r--cutlass-example/cutlass/core_io.h44
-rw-r--r--cutlass-example/cutlass/cutlass.h73
-rw-r--r--cutlass-example/cutlass/fragment.h278
-rw-r--r--cutlass-example/cutlass/fragment_load_store.h135
-rw-r--r--cutlass-example/cutlass/fragment_multiply_add.h149
-rw-r--r--cutlass-example/cutlass/gemm/clear_accumulators.h57
-rw-r--r--cutlass-example/cutlass/gemm/dgemm_traits.h127
-rw-r--r--cutlass-example/cutlass/gemm/gemm.h344
-rw-r--r--cutlass-example/cutlass/gemm/gemm_epilogue.h231
-rw-r--r--cutlass-example/cutlass/gemm/gemm_epilogue_traits.h331
-rw-r--r--cutlass-example/cutlass/gemm/gemm_global_stream.h182
-rw-r--r--cutlass-example/cutlass/gemm/gemm_global_tile.h541
-rw-r--r--cutlass-example/cutlass/gemm/gemm_operand.h141
-rw-r--r--cutlass-example/cutlass/gemm/gemm_shared_stream.h113
-rw-r--r--cutlass-example/cutlass/gemm/gemm_shared_tile.h417
-rw-r--r--cutlass-example/cutlass/gemm/gemm_traits.h818
-rw-r--r--cutlass-example/cutlass/gemm/hgemm_global_tile.h90
-rw-r--r--cutlass-example/cutlass/gemm/hgemm_multiply_add.h104
-rw-r--r--cutlass-example/cutlass/gemm/hgemm_swizzle.h94
-rw-r--r--cutlass-example/cutlass/gemm/hgemm_traits.h397
-rw-r--r--cutlass-example/cutlass/gemm/identity_block_swizzle.h48
-rw-r--r--cutlass-example/cutlass/gemm/igemm_epilogue.h320
-rw-r--r--cutlass-example/cutlass/gemm/igemm_global_tile.h161
-rw-r--r--cutlass-example/cutlass/gemm/igemm_multiply_add.h89
-rw-r--r--cutlass-example/cutlass/gemm/igemm_swizzle.h115
-rw-r--r--cutlass-example/cutlass/gemm/igemm_traits.h539
-rw-r--r--cutlass-example/cutlass/gemm/linear_scaling.h85
-rw-r--r--cutlass-example/cutlass/gemm/sgemm_traits.h127
-rw-r--r--cutlass-example/cutlass/gemm/thread_multiply_add.h84
-rw-r--r--cutlass-example/cutlass/gemm/wmma_gemm_epilogue_traits.h161
-rw-r--r--cutlass-example/cutlass/gemm/wmma_gemm_global_tile.h211
-rw-r--r--cutlass-example/cutlass/gemm/wmma_gemm_multiply_add.h108
-rw-r--r--cutlass-example/cutlass/gemm/wmma_gemm_shared_tile.h240
-rw-r--r--cutlass-example/cutlass/gemm/wmma_gemm_traits.h574
-rw-r--r--cutlass-example/cutlass/iterator_access.h318
-rw-r--r--cutlass-example/cutlass/load_store.h222
-rw-r--r--cutlass-example/cutlass/matrix_traits.h48
-rw-r--r--cutlass-example/cutlass/predicate_vector.h493
-rw-r--r--cutlass-example/cutlass/reshape_tile.h58
-rw-r--r--cutlass-example/cutlass/shape.h305
-rw-r--r--cutlass-example/cutlass/tensor_ref.h151
-rw-r--r--cutlass-example/cutlass/tensor_view.h172
-rw-r--r--cutlass-example/cutlass/tile_iterator.h899
-rw-r--r--cutlass-example/cutlass/tile_traits_standard.h238
-rw-r--r--cutlass-example/cutlass/util/cutlass_math.h131
-rw-r--r--cutlass-example/cutlass/util/debug.h122
-rw-r--r--cutlass-example/cutlass/util/platform.h801
-rw-r--r--cutlass-example/cutlass/vector.h229
-rw-r--r--cutlass-example/cutlass/wmma_matrix.h193
-rw-r--r--cutlass-example/cutlass_example.cu355
-rw-r--r--cutlass-example/device_memory.h178
-rw-r--r--cutlass-example/exceptions.h62
-rw-r--r--cutlass-example/executionFlow262
-rw-r--r--cutlass-example/gemm.h152
-rw-r--r--cutlass-example/gemm_testbed.h462
-rw-r--r--cutlass-example/gpgpusim.config151
-rwxr-xr-xcutlass-example/gpuwattch_gtx1080Ti.xml538
-rw-r--r--cutlass-example/half.h743
-rw-r--r--cutlass-example/host_tensor.h365
-rw-r--r--cutlass-example/host_tensor_view.h542
-rwxr-xr-xcutlass-example/launch.sh134
-rw-r--r--cutlass-example/tensor_view_io.h61
-rw-r--r--cutlass-example/type_traits.h160
68 files changed, 0 insertions, 16832 deletions
diff --git a/cutlass-example/Makefile b/cutlass-example/Makefile
deleted file mode 100644
index f72b732..0000000
--- a/cutlass-example/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) 1993-2017, NVIDIA CORPORATION. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of NVIDIA CORPORATION nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-CC = nvcc
-src = $(wildcard *.cu)
-obj = $(src:.c=.o)
-INC_DIR = ./
-
-
-#LDFLAGS = -g -G --gpu-architecture=compute_70 --gpu-code=compute_70 -lcudart -I$(INC_DIR)
-#LDFLAGS = -O0 -Xcicc -O0 -Xptxas -O0 --gpu-architecture=compute_70 --gpu-code=compute_70 -lcudart -I$(INC_DIR)
-LDFLAGS = --gpu-architecture=compute_70 --gpu-code=compute_70 -lcudart -I$(INC_DIR)
-
-myprog: $(obj)
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
-
-clean:
- rm -rf gemm_tt_*
- rm -rf host_results_*
- rm -rf gpgpusim_power_report__*
- rm -rf _cuobjdump*
- rm -rf gpgpu_inst_stats.txt
- rm -rf myprog
- echo Clean done
diff --git a/cutlass-example/command_line.h b/cutlass-example/command_line.h
deleted file mode 100644
index 8f2b17a..0000000
--- a/cutlass-example/command_line.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are not permitted.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************/
-
-#pragma once
-
-/**
- * \file
- * Utility for parsing command line arguments
- */
-
-#include <iostream>
-#include <limits>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <cuda_runtime.h>
-
-namespace cutlass {
-
-/******************************************************************************
- * command_line
- ******************************************************************************/
-
-/**
- * Utility for parsing command line arguments
- */
-struct CommandLine {
- std::vector<std::string> keys;
- std::vector<std::string> values;
- std::vector<std::string> args;
-
- /**
- * Constructor
- */
- CommandLine(int argc, const char** argv) : keys(10), values(10) {
- using namespace std;
-
- for (int i = 1; i < argc; i++) {
- string arg = argv[i];
-
- if ((arg[0] != '-') || (arg[1] != '-')) {
- args.push_back(arg);
- continue;
- }
-
- string::size_type pos;
- string key, val;
- if ((pos = arg.find('=')) == string::npos) {
- key = string(arg, 2, arg.length() - 2);
- val = "";
- } else {
- key = string(arg, 2, pos - 2);
- val = string(arg, pos + 1, arg.length() - 1);
- }
-
- keys.push_back(key);
- values.push_back(val);
- }
- }
-
- /**
- * Checks whether a flag "--<flag>" is present in the commandline
- */
- bool check_cmd_line_flag(const char* arg_name) const {
- using namespace std;
-
- for (int i = 0; i < int(keys.size()); ++i) {
- if (keys[i] == string(arg_name)) return true;
- }
- return false;
- }
-
- /**
- * Returns number of naked (non-flag and non-key-value) commandline parameters
- */
- template <typename value_t>
- int num_naked_args() const {
- return args.size();
- }
-
- /**
- * Returns the commandline parameter for a given index (not including flags)
- */
- template <typename value_t>
- void get_cmd_line_argument(int index, value_t& val) const {
- using namespace std;
- if (index < args.size()) {
- istringstream str_stream(args[index]);
- str_stream >> val;
- }
- }
-
- /**
- * Returns the commandline parameter for a given index (not including flags)
- */
- void get_cmd_line_argument(const char* arg_name, bool& val, bool _default = true) const {
- val = _default;
- if (check_cmd_line_flag(arg_name)) {
- std::string value;
- get_cmd_line_argument(arg_name, value);
-
- val = !(value == "0" || value == "false");
- }
- }
-
- /**
- * Returns the value specified for a given commandline parameter --<flag>=<value>
- */
- template <typename value_t>
- void get_cmd_line_argument(const char* arg_name,
- value_t& val,
- value_t const& _default = value_t()) const {
- using namespace std;
-
- val = _default;
-
- for (int i = 0; i < int(keys.size()); ++i) {
- if (keys[i] == string(arg_name)) {
- istringstream str_stream(values[i]);
- str_stream >> val;
- }
- }
- }
-
- /**
- * Returns the values specified for a given commandline parameter --<flag>=<value>,<value>*
- */
- template <typename value_t>
- void get_cmd_line_arguments(const char* arg_name,
- std::vector<value_t>& vals,
- char sep = ',') const {
- using namespace std;
-
- if (check_cmd_line_flag(arg_name)) {
- // Clear any default values
- vals.clear();
-
- // Recover from multi-value string
- for (int i = 0; i < keys.size(); ++i) {
- if (keys[i] == string(arg_name)) {
- string val_string(values[i]);
- istringstream str_stream(val_string);
- string::size_type old_pos = 0;
- string::size_type new_pos = 0;
-
- // Iterate <sep>-delimited values
- value_t val;
- while ((new_pos = val_string.find(sep, old_pos)) != string::npos) {
- if (new_pos != old_pos) {
- str_stream.width(new_pos - old_pos);
- str_stream >> val;
- vals.push_back(val);
- }
-
- // skip over delimiter
- str_stream.ignore(1);
- old_pos = new_pos + 1;
- }
-
- // Read last value
- str_stream >> val;
- vals.push_back(val);
- }
- }
- }
- }
-
- /**
- * Returns the values specified for a given commandline parameter
- * --<flag>=<key:value>,<key:value>*
- */
- void get_cmd_line_argument_pairs(const char* arg_name,
- std::vector<std::pair<std::string, std::string> >& tokens,
- char delim = ',',
- char sep = ':') const {
- if (check_cmd_line_flag(arg_name)) {
- std::string value;
- get_cmd_line_argument(arg_name, value);
-
- tokenize(tokens, value, delim, sep);
- }
- }
-
- /**
- * The number of pairs parsed
- */
- int parsed_argc() const { return (int)keys.size(); }
-
- //-------------------------------------------------------------------------
- // Utility functions
- //-------------------------------------------------------------------------
-
- /// Tokenizes a comma-delimited list of string pairs delimited by ':'
- static void tokenize(std::vector<std::pair<std::string, std::string> >& tokens,
- std::string const& str,
- char delim = ',',
- char sep = ':') {
- // Home-built to avoid Boost dependency
- size_t s_idx = 0;
- size_t d_idx = std::string::npos;
- while (s_idx < str.size()) {
- d_idx = str.find_first_of(delim, s_idx);
-
- size_t end_idx = (d_idx != std::string::npos ? d_idx : str.size());
- size_t sep_idx = str.find_first_of(sep, s_idx);
- size_t offset = 1;
- if (sep_idx == std::string::npos || sep_idx >= end_idx) {
- sep_idx = end_idx;
- offset = 0;
- }
-
- std::pair<std::string, std::string> item(
- str.substr(s_idx, sep_idx - s_idx),
- str.substr(sep_idx + offset, end_idx - sep_idx - offset));
-
- tokens.push_back(item);
- s_idx = end_idx + 1;
- }
- }
-
- /// Tokenizes a comma-delimited list of string pairs delimited by ':'
- static void tokenize(std::vector<std::string>& tokens,
- std::string const& str,
- char delim = ',',
- char sep = ':') {
- typedef std::vector<std::pair<std::string, std::string> > TokenVector;
- typedef TokenVector::const_iterator token_iterator;
-
- std::vector<std::pair<std::string, std::string> > token_pairs;
- tokenize(token_pairs, str, delim, sep);
- for (token_iterator tok = token_pairs.begin(); tok != token_pairs.end(); ++tok) {
- tokens.push_back(tok->first);
- }
- }
-};
-
-} // namespace cutlass
diff --git a/cutlass-example/config_fermi_islip.icnt b/cutlass-example/config_fermi_islip.icnt
deleted file mode 100644
index 3b8b496..0000000
--- a/cutlass-example/config_fermi_islip.icnt
+++ /dev/null
@@ -1,70 +0,0 @@
-//21*1 fly with 32 flits per packet under gpgpusim injection mode
-use_map = 0;
-flit_size = 32;
-
-// currently we do not use this, see subnets below
-network_count = 2;
-
-// Topology
-topology = fly;
-k = 102;
-n = 1;
-
-// Routing
-
-routing_function = dest_tag;
-
-// Flow control
-
-num_vcs = 1;
-vc_buf_size = 8;
-
-wait_for_tail_credit = 0;
-
-// Router architecture
-
-vc_allocator = islip; //separable_input_first;
-sw_allocator = islip; //separable_input_first;
-alloc_iters = 1;
-
-credit_delay = 0;
-routing_delay = 0;
-vc_alloc_delay = 1;
-sw_alloc_delay = 1;
-
-input_speedup = 2;
-output_speedup = 1;
-internal_speedup = 1.0;
-
-// Traffic, GPGPU-Sim does not use this
-
-traffic = uniform;
-packet_size ={{1,2,3,4},{10,20}};
-packet_size_rate={{1,1,1,1},{2,1}};
-
-// Simulation - Don't change
-
-sim_type = gpgpusim;
-//sim_type = latency;
-injection_rate = 0.1;
-
-subnets = 2;
-
-// Always use read and write no matter following line
-//use_read_write = 1;
-
-
-read_request_subnet = 0;
-read_reply_subnet = 1;
-write_request_subnet = 0;
-write_reply_subnet = 1;
-
-read_request_begin_vc = 0;
-read_request_end_vc = 0;
-write_request_begin_vc = 0;
-write_request_end_vc = 0;
-read_reply_begin_vc = 0;
-read_reply_end_vc = 0;
-write_reply_begin_vc = 0;
-write_reply_end_vc = 0;
-
diff --git a/cutlass-example/cutlass/convert.h b/cutlass-example/cutlass/convert.h
deleted file mode 100644
index 933d68a..0000000
--- a/cutlass-example/cutlass/convert.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*!
- \file
- \brief Defines conversion operations among Fragments of different base type.
-*/
-#pragma once
-
-#include <cutlass/fragment.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename InputFragment_, typename OutputFragment_>
-struct Convert {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename InputScalar_, typename OutputScalar_, int kScalars_>
-struct Convert<Fragment<InputScalar_, kScalars_>, Fragment<OutputScalar_, kScalars_> > {
- /// The input fragment.
- typedef Fragment<InputScalar_, kScalars_> InputFragment;
- /// The output fragment.
- typedef Fragment<OutputScalar_, kScalars_> OutputFragment;
-
- /// Ctor.
- CUTLASS_DEVICE Convert() {}
-
- /// Transform a fragment.
- CUTLASS_DEVICE void transform(InputFragment const& src, OutputFragment& dst) {
- transform(src, 0, dst);
- }
-
- /// Transform a fragment.
- template <typename Fragment_>
- CUTLASS_DEVICE void transform(Fragment_ const& src, int offset, OutputFragment& dst) {
- for (int i = 0; i < kScalars_; ++i) {
- dst[i] = static_cast<OutputScalar_>(src[i + offset]);
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Fragment_>
-struct Copy {
- /// The input fragment.
- typedef Fragment_ InputFragment;
- /// The output fragment.
- typedef Fragment_ OutputFragment;
-
- /// Ctor.
- CUTLASS_DEVICE Copy() {}
-
- /// Transform a fragment.
- CUTLASS_DEVICE void transform(Fragment_ const& src, Fragment_& dst) { transform(src, 0, dst); }
-
- /// Transform a fragment.
- template <typename InputFragment_>
- CUTLASS_DEVICE void transform(InputFragment_ const& src, int offset, Fragment_& dst) {
- if (sizeof(typename Fragment_::Element) == 8) {
- uint64_t const* src_ptr = reinterpret_cast<uint64_t const*>(&src[offset]);
- uint64_t* dst_ptr = reinterpret_cast<uint64_t*>(&dst[0]);
- for (int i = 0; i < sizeof(Fragment_) / 8; ++i) {
- dst_ptr[i] = src_ptr[i];
- }
- } else {
- uint32_t const* src_ptr = reinterpret_cast<uint32_t const*>(&src[offset]);
- uint32_t* dst_ptr = reinterpret_cast<uint32_t*>(&dst[0]);
- for (int i = 0; i < sizeof(Fragment_) / 4; ++i) {
- dst_ptr[i] = src_ptr[i];
- }
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/coord.h b/cutlass-example/cutlass/coord.h
deleted file mode 100644
index 431c9bf..0000000
--- a/cutlass-example/cutlass/coord.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief A Coord is a coordinate of arbitrary rank into a tensor or matrix
-*/
-
-#pragma once
-
-#include <cutlass/cutlass.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Describes identity elements
-struct Identity {
- /// Enumeration describing identity elements. Value assignments are significant.
- /// Feel free to add or multiply by these, respectively.
- enum Kind { Additive = 0, Multiplicative = 1 };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Statically-sized array specifying Coords within a tensor
-template <int N_>
-struct Coord {
- //
- // Type and constant definitions
- //
-
- static int const N = N_;
-
- //
- // Data members
- //
-
- /// Indices
- int idx[N];
-
- //
- // Methods
- //
-
- /// Default ctor initializes uniformly
- CUTLASS_HOST_DEVICE
- Coord(int value = 0) {
- for (int i = 0; i < N; ++i) {
- idx[i] = value;
- }
- }
-
- /// Constructs from an array of integers
- CUTLASS_HOST_DEVICE
- Coord(int _idx[]) {
- for (int i = 0; i < N; ++i) {
- idx[i] = _idx[i];
- }
- }
-
- /// Element-wise addition
- CUTLASS_HOST_DEVICE
- Coord operator+(Coord const& b) const {
- Coord c;
- for (int i = 0; i < N; ++i) {
- c.idx[i] = idx[i] + b.idx[i];
- }
- return c;
- }
-
- /// Element-wise subtraction
- CUTLASS_HOST_DEVICE
- Coord operator-(Coord const& b) const {
- Coord c;
- for (int i = 0; i < N; ++i) {
- c.idx[i] = idx[i] - b.idx[i];
- }
- return c;
- }
-
- /// Element-wise multiplication
- CUTLASS_HOST_DEVICE
- Coord operator*(Coord const& b) const {
- Coord c;
- for (int i = 0; i < N; ++i) {
- c.idx[i] = idx[i] * b.idx[i];
- }
- return c;
- }
-
- /// Element-wise division
- CUTLASS_HOST_DEVICE
- Coord operator/(Coord const& b) const {
- Coord c;
- for (int i = 0; i < N; ++i) {
- c.idx[i] = idx[i] / b.idx[i];
- }
- return c;
- }
-
- /// In-place addition
- CUTLASS_HOST_DEVICE
- Coord& operator+=(Coord const& b) {
- for (int i = 0; i < N; ++i) {
- idx[i] += b.idx[i];
- }
- return *this;
- }
-
- /// In-place subtraction
- CUTLASS_HOST_DEVICE
- Coord& operator-=(Coord const& b) {
- for (int i = 0; i < N; ++i) {
- idx[i] -= b.idx[i];
- }
- return *this;
- }
-
- /// In-place multiplication
- CUTLASS_HOST_DEVICE
- Coord& operator*=(Coord const& b) {
- for (int i = 0; i < N; ++i) {
- idx[i] *= b.idx[i];
- }
- return *this;
- }
-
- /// In-place division
- CUTLASS_HOST_DEVICE
- Coord& operator/=(Coord const& b) {
- for (int i = 0; i < N; ++i) {
- idx[i] /= b.idx[i];
- }
- return *this;
- }
-
- /// Member access operator
- CUTLASS_HOST_DEVICE int& operator[](int dim) { return idx[dim]; }
-
- /// Member access operator
- CUTLASS_HOST_DEVICE int const& operator[](int dim) const { return idx[dim]; }
-
- /// Computes the dot product of two Coord instances
- template <typename T>
- CUTLASS_HOST_DEVICE T dot(Coord const& b, T sum) const {
- for (int i = 0; i < N; ++i) {
- sum += idx[i] * b.idx[i];
- }
- return sum;
- }
-
- /// Computes the dot product of two Coord instances
- template <typename T>
- CUTLASS_HOST_DEVICE T dot(Coord const& b) const {
- T sum = T(0);
- for (int i = 0; i < N; ++i) {
- sum += idx[i] * b.idx[i];
- }
- return sum;
- }
-
- /// Gets the index of a given Coord element
- template <int Dim>
- CUTLASS_HOST_DEVICE int& at() {
- return idx[Dim];
- }
-
- /// Access via index; may limit unrolling potential
- CUTLASS_HOST_DEVICE
- int& at(int dim) { return idx[dim]; }
-
- /// Gets the index of a given Coord element
- template <int Dim>
- CUTLASS_HOST_DEVICE int const& at() const {
- return idx[Dim];
- }
-
- /// Access via index; may limit unrolling potential
- CUTLASS_HOST_DEVICE
- int const& at(int dim) const { return idx[dim]; }
-
- /// Determines if two Coord<> objects are equal
- CUTLASS_HOST_DEVICE
- bool operator==(Coord<N> const& b) const {
- bool equal = true;
- for (int i = 0; equal && i < N; ++i) {
- equal = (idx[i] == b.idx[i]);
- }
- return equal;
- }
-
- /// Not equal
- CUTLASS_HOST_DEVICE
- bool operator!=(Coord<N> const& b) const { return !(*this == b); }
-
- /// Clamps a coordinate to a range specified by maximum and minimum values
- CUTLASS_HOST_DEVICE
- Coord& clamp(Coord<N> const& max, Coord<N> const& min = Coord<N>()) {
- for (int i = 0; i < N; ++i) {
- idx[i] = __NV_STD_MAX(__NV_STD_MIN(idx[i], max.idx[i]), min.idx[i]);
- }
- return *this;
- }
-
- /// Returns the product of all elements
- CUTLASS_HOST_DEVICE
- int count() const {
- int product = idx[0];
- for (int i = 1; i < N; ++i) {
- product *= idx[i];
- }
- return product;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Helper to make a 2-element coordinate
-CUTLASS_HOST_DEVICE
-Coord<1> make_Coord(int _0) {
- int values[1] = {_0};
- return Coord<1>(values);
-}
-
-/// Helper to make a 2-element coordinate
-CUTLASS_HOST_DEVICE
-Coord<2> make_Coord(int _0, int _1) {
- int values[2] = {_0, _1};
- return Coord<2>(values);
-}
-
-/// Helper to make a 3-element coordinate
-CUTLASS_HOST_DEVICE
-Coord<3> make_Coord(int _0, int _1, int _2) {
- int values[3] = {_0, _1, _2};
- return Coord<3>(values);
-}
-
-/// Helper to make a 4-element coordinate
-CUTLASS_HOST_DEVICE
-Coord<4> make_Coord(int _0, int _1, int _2, int _3) {
- int values[4] = {_0, _1, _2, _3};
- return Coord<4>(values);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Getter
-CUTLASS_HOST_DEVICE
-Coord<2> get_Coord_hw(Coord<3> const& coord) { return make_Coord(coord[1], coord[2]); }
-
-/// Getter
-CUTLASS_HOST_DEVICE
-Coord<2> get_Coord_hw(Coord<4> const& coord) { return make_Coord(coord[1], coord[2]); }
-
-/// Getter
-CUTLASS_HOST_DEVICE
-Coord<3> get_Coord_hwc(Coord<4> const& coord) { return make_Coord(coord[1], coord[2], coord[3]); }
-
-/// Getter
-CUTLASS_HOST_DEVICE
-Coord<3> get_Coord_dhw(Coord<4> const& coord) { return make_Coord(coord[0], coord[1], coord[2]); }
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/core_io.h b/cutlass-example/cutlass/core_io.h
deleted file mode 100644
index cceea4c..0000000
--- a/cutlass-example/cutlass/core_io.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-#pragma once
-
-/*! \file
- \brief Helpers for printing cutlass/core objects
-*/
-
-#pragma once
-
-#include <iosfwd>
-#include <typeinfo>
-
-#include <cutlass/coord.h>
-
-template <int Rank>
-std::ostream& operator<<(std::ostream& out, cutlass::Coord<Rank> const& coord) {
- for (int i = 0; i < Rank; ++i) {
- out << (i ? ", " : "") << coord.idx[i];
- }
- return out;
-}
diff --git a/cutlass-example/cutlass/cutlass.h b/cutlass-example/cutlass/cutlass.h
deleted file mode 100644
index 19600ec..0000000
--- a/cutlass-example/cutlass/cutlass.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-
-/*! \file
- \brief Basic include for CUTLASS macros
-*/
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#define CUTLASS_MAJOR 1
-#define CUTLASS_MINOR 0
-#define CUTLASS_PATCH 1
-#define CUTLASS_VERSION ((CUTLASS_MAJOR)*100 + (CUTLASS_MINOR)*10 + CUTLASS_PATCH)
-
-#ifdef __NVCC__
-#define CUTLASS_HOST_DEVICE __forceinline__ __device__ __host__
-#define CUTLASS_DEVICE __forceinline__ __device__
-#elif defined(__CUDACC_RTC__)
-#define CUTLASS_HOST_DEVICE __forceinline__ __device__
-#define CUTLASS_DEVICE __forceinline__ __device__
-#else
-#define CUTLASS_HOST_DEVICE
-// CUTLASS_DEVICE is an error if not compiling device code
-#endif
-
-// CUTLASS_PRAGMA_UNROLL inserts a CUTLASS_PRAGMA_UNROLL if supported by the compiler
-#if defined(__CUDA_ARCH__)
-#if defined(_MSC_VER)
-#define CUTLASS_PRAGMA_UNROLL __pragma("unroll")
-#define CUTLASS_PRAGMA_NO_UNROLL __pragma("unroll 1")
-#else
-#define CUTLASS_PRAGMA_UNROLL _Pragma("unroll")
-#define CUTLASS_PRAGMA_NO_UNROLL _Pragma("unroll 1")
-#endif
-#else
-#define CUTLASS_PRAGMA_UNROLL
-#define CUTLASS_PRAGMA_NO_UNROLL
-#endif
-
-#define CUTLASS_ASSERT(x) assert(x)
-
-namespace cutlass {
-
-/// NVIDIA GPU Warp size
-static const int kWarpSize = 32;
-
-} // namespace cutlass
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/cutlass-example/cutlass/fragment.h b/cutlass-example/cutlass/fragment.h
deleted file mode 100644
index 886b114..0000000
--- a/cutlass-example/cutlass/fragment.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines Fragment, a statically-sized array for storing parts of matrices within a
- thread's registers.
-*/
-#pragma once
-
-#include <assert.h>
-#include <cutlass/shape.h>
-#include <cutlass/util/cutlass_math.h>
-#include <cutlass/vector.h>
-
-namespace cutlass {
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup fragment_concept Fragment Concept
-@{
-
-\ref fragment_concept is a statically sized array for storing parts of tiles held by individual CUDA
-threads.
-
-@par \ref fragment_concept
- Types satisfying \ref fragment_concept define the following members
- - <b>Element</b> - type of each access held within the fragment
- - <b>kElements</b> - number of elements stored by the fragment
- - <b>clear()</b> - overwrites the fragment storage with zeros
- - <b>Element & operator[](int i)</b> - by-reference access of the ith element
- - <b>Element const & operator[](int i) const</b> - const by-reference access of the ith element
-@}
-*/
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup fragment_iterator_concept Fragment Iterator Concept
-@{
-
-\ref fragment_iterator_concept provides structured access to the elements within a fragment with an
-optional bitcast to the desired access type
-
-@par \ref fragment_iterator_concept
- Types satisfying \ref fragment_iterator_concept define the following members
- - <b>AccessType& operator[](int i)</b> - provides access to the ith element of the fragment
- - <b>AccessType& at(int d, int h, int w, int c)</b> - applies \ref layout_concept to fragment and
-provides access to element at (d, h, w, c)
-
-@}
-*/
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <int kAlignment_>
-struct StorageType {
- typedef uint64_t Type;
-};
-template <>
-struct StorageType<4> {
- typedef uint32_t Type;
-};
-template <>
-struct StorageType<2> {
- typedef uint16_t Type;
-};
-template <>
-struct StorageType<1> {
- typedef uint8_t Type;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief A template defining \ref fragment_concept
-* @concept{fragment_concept}
-*/
-template <typename Element_, int kElements_, size_t kAlignment_ = 16>
-struct Fragment : public AlignedStruct<kAlignment_> {
- /// Make sure the alignment makes sense wrt the size of elements.
- static_assert(kAlignment_ == 16 || kAlignment_ >= sizeof(Element_), "Alignment is too small");
- /// Alignment must be a power of two
- static_assert(is_pow2<kAlignment_>::value, "Alignment must be a power of two");
-
- /// This class.
- typedef Fragment<Element_, kElements_> This_;
- /// The element.
- typedef Element_ Element;
- /// The number of elements.
- static int const kElements = kElements_;
-
- /// Clear a fragment.
- CUTLASS_DEVICE void clear() {
- // Avoid element-wise access for sub 32b element type
- if (kAlignment_ >= 8 && (kElements * sizeof(Element)) % 8 == 0) {
- uint64_t* ptr = reinterpret_cast<uint64_t*>(storage);
- for (int i = 0; i < (kElements * sizeof(Element)) / 8; ++i) {
- ptr[i] = uint64_t(0);
- }
- } else if (kAlignment_ >= 4 && (kElements * sizeof(Element)) % 4 == 0) {
- uint32_t* ptr = reinterpret_cast<uint32_t*>(storage);
- for (int i = 0; i < (kElements * sizeof(Element)) / 4; ++i) {
- ptr[i] = uint32_t(0);
- }
- } else if (kAlignment_ >= 2 && (kElements * sizeof(Element)) % 2 == 0) {
- uint16_t* ptr = reinterpret_cast<uint16_t*>(storage);
- for (int i = 0; i < (kElements * sizeof(Element)) / 2; ++i) {
- ptr[i] = uint16_t(0);
- }
- } else {
- for (int i = 0; i < kElements; ++i) {
- storage[i] = 0;
- }
- }
- }
-
- /// The accessor.
- CUTLASS_DEVICE Element& operator[](int i) {
- assert(i < kElements_);
- return reinterpret_cast<Element*>(storage)[i];
- }
-
- /// The accessor.
- CUTLASS_DEVICE Element const& operator[](int i) const {
- assert(i < kElements_);
- return reinterpret_cast<Element const*>(storage)[i];
- }
-
- private:
- /// Storage type to use for Elements
- typedef typename StorageType<kAlignment_>::Type StorageType;
-
- /// Number of elements in the storage
- static int const kStorageCount =
- (sizeof(Element_) * kElements_ + sizeof(StorageType) - 1) / sizeof(StorageType);
- /// The storage.
- StorageType storage[kStorageCount];
-
- /// Ensure that there's enough storage for all elements
- static_assert(sizeof(StorageType) <= kAlignment_, "StorageType is too big for given alignment");
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief A template defining \ref fragment_iterator_concept
-* @concept{fragment_iterator_concept}
-*/
-template <typename Fragment_, typename Iterations_, typename AccessType_>
-struct FragmentIterator {
- /// This class.
- typedef FragmentIterator<Fragment_, Iterations_, AccessType_> This_;
- /// The fragment.
- typedef Fragment_ Fragment;
- /// The number of iterations.
- typedef Iterations_ Iterations;
- /// The access type.
- typedef AccessType_ AccessType;
-
- /// The element.
- typedef typename Fragment::Element Element;
- /// The number of elements per access.
- static int const kElementsPerAccess = (int)(sizeof(AccessType) / sizeof(Element));
- /// The shape of the the fragment.
- typedef typename ShapeMul<Iterations, Shape<1, 1, 1, kElementsPerAccess> >::Shape FragmentShape;
- /// The linear strides for iterations.
- typedef typename ShapeStrides<FragmentShape, kElementsPerAccess>::Shape Strides;
-
- /// Ctor.
- template <typename OtherFragment_>
- CUTLASS_DEVICE FragmentIterator(OtherFragment_& fragment, int offset = 0)
- : pointer(reinterpret_cast<Element*>(&fragment[offset])) {
- static_assert(OtherFragment_::kElements >= Fragment::kElements, "");
- }
-
- /// The accessor.
- CUTLASS_DEVICE AccessType const& at(int d, int h, int w, int c = 0) const {
- int const imm = ComputeOffsetFromStrides<Strides>::get(d, h, w, c);
- return reinterpret_cast<AccessType const&>(pointer[imm]);
- }
-
- /// The accessor.
- CUTLASS_DEVICE AccessType& at(int d, int h, int w, int c = 0) {
- int const imm = ComputeOffsetFromStrides<Strides>::get(d, h, w, c);
- return reinterpret_cast<AccessType&>(pointer[imm]);
- }
-
- /// The accessor.
- CUTLASS_DEVICE AccessType const& operator[](int i) const {
- return reinterpret_cast<AccessType const&>(pointer[i * kElementsPerAccess]);
- }
-
- /// The accessor.
- CUTLASS_DEVICE AccessType& operator[](int i) {
- return reinterpret_cast<AccessType&>(pointer[i * kElementsPerAccess]);
- }
-
- /// Is the iterator valid?
- CUTLASS_DEVICE bool valid(int d, int h, int w, int c) const { return true; }
-
- /// The pointer.
- Element* pointer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Fragment_, typename Iterations_, typename AccessType_>
-struct FragmentConstIterator {
- /// This class.
- typedef FragmentIterator<Fragment_, Iterations_, AccessType_> This_;
- /// The fragment.
- typedef Fragment_ Fragment;
- /// The number of iterations.
- typedef Iterations_ Iterations;
- /// The access type.
- typedef AccessType_ AccessType;
-
- /// The element.
- typedef typename Fragment::Element Element;
- /// The number of elements per access.
- static int const kElementsPerAccess = (int)(sizeof(AccessType) / sizeof(Element));
- /// The shape of the the fragment.
- typedef typename ShapeMul<Iterations, Shape<1, 1, 1, kElementsPerAccess> >::Shape FragmentShape;
- /// The linear strides for iterations.
- typedef typename ShapeStrides<FragmentShape, kElementsPerAccess>::Shape IterationsStrides;
-
- /// Ctor.
- template <typename OtherFragment_>
- CUTLASS_DEVICE FragmentConstIterator(OtherFragment_& fragment, int offset = 0)
- : pointer(reinterpret_cast<Element const*>(&fragment[offset])) {
- static_assert(OtherFragment_::kElements >= Fragment::kElements, "");
- }
- /// Create from non-constant FragmentIterator
- CUTLASS_DEVICE FragmentConstIterator(
- FragmentIterator<Fragment_, Iterations_, AccessType_> const& rhs_)
- : pointer(reinterpret_cast<Element const*>(rhs_.offset)) {}
-
- /// The accessor.
- CUTLASS_DEVICE AccessType const& at(int d, int h, int w, int c = 0) const {
- int const imm = ComputeOffsetFromStrides<IterationsStrides>::get(d, h, w, c);
- return reinterpret_cast<AccessType const&>(pointer[imm]);
- }
-
- /// The accessor.
- CUTLASS_DEVICE AccessType const& operator[](int i) const {
- return reinterpret_cast<AccessType const&>(pointer[i * kElementsPerAccess]);
- }
-
- /// Is the iterator valid?
- CUTLASS_DEVICE bool valid(int d, int h, int w, int c) const { return true; }
-
- /// The pointer.
- Element const* pointer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/fragment_load_store.h b/cutlass-example/cutlass/fragment_load_store.h
deleted file mode 100644
index a7d272e..0000000
--- a/cutlass-example/cutlass/fragment_load_store.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines accessors for loading and storing fragments to memory efficiently.
-*/
-#pragma once
-
-#include <cutlass/load_store.h>
-#include <cutlass/vector.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <IteratorFragment::Kind kIteratorFragment,
- int kAccessSize,
- typename Scalar_,
- MemorySpace::Kind Memory_,
- typename FragmentElement_,
- int kStride>
-struct FragmentLoad {};
-
-template <int kAccessSize,
- typename Scalar_,
- MemorySpace::Kind Memory_,
- typename FragmentElement_,
- int kStride>
-struct FragmentLoad<IteratorFragment::kWmmaMatrix,
- kAccessSize,
- Scalar_,
- Memory_,
- FragmentElement_,
- kStride> {
- /// The output type.
- typedef FragmentElement_ AccessType;
-
- /// The load function.
- static CUTLASS_DEVICE void load(AccessType& value, Scalar_ const* pointer, int offset) {
- value.load(&pointer[offset], kStride);
- }
-};
-
-template <int kAccessSize,
- typename Scalar_,
- MemorySpace::Kind Memory_,
- typename FragmentElement_,
- int kStride>
-struct FragmentLoad<IteratorFragment::kScalar,
- kAccessSize,
- Scalar_,
- Memory_,
- FragmentElement_,
- kStride> {
- /// The output type.
- typedef typename Vectorize<Scalar_, kAccessSize>::Type AccessType;
-
- /// The load function.
- static CUTLASS_DEVICE void load(AccessType& value, Scalar_ const* pointer, int offset) {
- Load<Scalar_, kAccessSize, Memory_>::load(value, pointer, offset);
- }
-};
-
-template <IteratorFragment::Kind kIteratorFragment,
- int kAccessSize,
- typename Scalar_,
- MemorySpace::Kind Memory_,
- typename FragmentElement_,
- int kStride>
-struct FragmentStore {};
-
-template <int kAccessSize,
- typename Scalar_,
- MemorySpace::Kind Memory_,
- typename FragmentElement_,
- int kStride>
-struct FragmentStore<IteratorFragment::kWmmaMatrix,
- kAccessSize,
- Scalar_,
- Memory_,
- FragmentElement_,
- kStride> {
- /// The input type.
- typedef FragmentElement_ AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void store(AccessType const& value, Scalar_* pointer, int offset) {
- value.store(&pointer[offset], kStride);
- }
-};
-
-template <int kAccessSize,
- typename Scalar_,
- MemorySpace::Kind Memory_,
- typename FragmentElement_,
- int kStride>
-struct FragmentStore<IteratorFragment::kScalar,
- kAccessSize,
- Scalar_,
- Memory_,
- FragmentElement_,
- kStride> {
- /// The input type.
- typedef typename Vectorize<Scalar_, kAccessSize>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void store(AccessType const& value, Scalar_* pointer, int offset) {
- Store<Scalar_, kAccessSize, Memory_>::store(value, pointer, offset);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} /// namespace cutlass
diff --git a/cutlass-example/cutlass/fragment_multiply_add.h b/cutlass-example/cutlass/fragment_multiply_add.h
deleted file mode 100644
index 36a4d6f..0000000
--- a/cutlass-example/cutlass/fragment_multiply_add.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines multiply-add operations on fragments within a thread.
-*/
-#pragma once
-
-#include <cutlass/fragment.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_>
-struct FragmentMultiplyAdd {
- /// The shape of the instruction.
- typedef Shape<1, 1, 1, 1> InstructionShape;
- /// The type for A.
- typedef Scalar_ ScalarA;
- /// The type for B.
- typedef Scalar_ ScalarB;
- /// The type for C and D.
- typedef Scalar_ ScalarC;
-
- /// Ctor.
- CUTLASS_DEVICE FragmentMultiplyAdd() {}
-
- /// Multiply : d = a*b.
- template <typename FragmentB_, typename FragmentCd_>
- CUTLASS_DEVICE void multiply(Scalar_ a, FragmentB_ const& b, FragmentCd_& d) {
- int const kReduction = FragmentB_::kElements / FragmentCd_::kElements;
- for (int j = 0; j < FragmentCd_::kElements; ++j) {
- d[j] = a * b[j * kReduction + 0];
- for (int k = 1; k < kReduction; ++k) {
- d[j] += a * b[j * kReduction + k];
- }
- }
- }
-
- /// Multiply : d = a*b + c.
- template <typename FragmentB_, typename FragmentCd_>
- CUTLASS_DEVICE void multiply_add(Scalar_ a,
- FragmentB_ const& b,
- FragmentCd_ const& c,
- FragmentCd_& d) {
- int const kReduction = FragmentB_::kElements / FragmentCd_::kElements;
- for (int j = 0; j < FragmentCd_::kElements; ++j) {
- d[j] = a * b[j * kReduction + 0] + c[j];
- for (int k = 1; k < kReduction; ++k) {
- d[j] += a * b[j * kReduction + k];
- }
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#if !defined(__CUDACC_RTC__) || defined(CUTLASS_NVRTC_HAS_FP16)
-template <>
-struct FragmentMultiplyAdd<half> {
- /// The shape of the instruction.
- typedef Shape<1, 1, 2, 1> InstructionShape;
- /// The type for A.
- typedef half ScalarA;
- /// The type for B.
- typedef half ScalarB;
- /// The type for C and D.
- typedef half ScalarC;
-
- /// Ctor.
- CUTLASS_DEVICE FragmentMultiplyAdd() {}
-
- /// Multiply : d = a*b.
- template <typename FragmentB_, typename FragmentCd_>
- CUTLASS_DEVICE void multiply(half a, FragmentB_ const& b, FragmentCd_& d) {
-#if defined(__CUDACC__) && __CUDA_ARCH__ >= 530
-
- // Assemble a half2 from a.
- __half2 const a_half2 = __half2half2(a);
- // The input.
- __half2 const* b_half2 = reinterpret_cast<__half2 const*>(&b[0]);
- // The output.
- __half2* d_half2 = reinterpret_cast<__half2*>(&d[0]);
-
- int const kReduction = FragmentB_::kElements / FragmentCd_::kElements;
- for (int j = 0; j < FragmentCd_::kElements / 2; ++j) {
- d_half2[j] = __hmul2(a_half2, b_half2[j * kReduction + 0]);
- for (int k = 1; k < kReduction; ++k) {
- d_half2[j] = __hfma2(a_half2, b_half2[j * kReduction + k], d_half2[j]);
- }
- }
-#endif
- }
-
- /// Multiply : d = a*b + c.
- template <typename FragmentB_, typename FragmentCd_>
- CUTLASS_DEVICE void multiply_add(half a,
- FragmentB_ const& b,
- FragmentCd_ const& c,
- FragmentCd_& d) {
-#if defined(__CUDACC__) && __CUDA_ARCH__ >= 530
- // Assemble a half2 from a.
- __half2 const a_half2 = __half2half2(a);
- // The inputs.
- __half2 const* b_half2 = reinterpret_cast<__half2 const*>(&b[0]);
- __half2 const* c_half2 = reinterpret_cast<__half2 const*>(&c[0]);
- // The output.
- __half2* d_half2 = reinterpret_cast<__half2*>(&d[0]);
-
- int const kReduction = (FragmentB_::kElements / FragmentCd_::kElements);
- for (int j = 0; j < FragmentCd_::kElements / 2; ++j) {
- d_half2[j] = __hfma2(a_half2, b_half2[j * kReduction + 0], c_half2[j]);
- for (int k = 1; k < kReduction; ++k) {
- d_half2[j] = __hfma2(a_half2, b_half2[j * kReduction + k], d_half2[j]);
- }
- }
-#endif
- }
-};
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/clear_accumulators.h b/cutlass-example/cutlass/gemm/clear_accumulators.h
deleted file mode 100644
index 441370f..0000000
--- a/cutlass-example/cutlass/gemm/clear_accumulators.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines abstractions for efficiently clearing accumulator tiles.
-*/
-#pragma once
-
-#include <cutlass/vector.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int kLanes_ = 1>
-struct ClearAccumulators {
- /// The shared storage.
- struct SharedStorage {};
-
- /// Ctor.
- CUTLASS_DEVICE ClearAccumulators() {}
- /// Ctor.
- CUTLASS_DEVICE ClearAccumulators(SharedStorage& shared_storage) {}
-
- /// Clear the fragment.
- template <typename Fragment_>
- CUTLASS_DEVICE void clear(Fragment_& fragment) {
- fragment.clear();
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/dgemm_traits.h b/cutlass-example/cutlass/gemm/dgemm_traits.h
deleted file mode 100644
index 0bbc221..0000000
--- a/cutlass-example/cutlass/gemm/dgemm_traits.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines structural traits of double-precision GEMM.
-*/
-#pragma once
-
-#include <cutlass/gemm/gemm.h>
-#include <cutlass/gemm/gemm_epilogue.h>
-#include <cutlass/gemm/gemm_epilogue_traits.h>
-#include <cutlass/gemm/gemm_global_tile.h>
-#include <cutlass/gemm/gemm_shared_tile.h>
-#include <cutlass/gemm/gemm_traits.h>
-#include <cutlass/gemm/thread_multiply_add.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The tile size for the GEMM KxNxM.
- typename OutputTile_,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_,
- /// The number of scalars per LDG for A.
- int kScalarsPerLdgA_ = 1,
- /// The number of scalars per LDG for B.
- int kScalarsPerLdgB_ = 1>
-struct DgemmConfig
- : public GemmConfig<
- /// The scalar type for A.
- double,
- /// The scalar type for B.
- double,
- /// The scalar type for C.
- double,
- /// The scalar type for D.
- double,
- /// The tile size for the GEMM KxNxM.
- OutputTile_,
- /// The functor to do the math in the main loop.
- ThreadMultiplyAdd<AccumulatorsPerThread_, Shape<1, 4, 8>, double, double, double>,
- /// The number of scalars per LDG for A.
- kScalarsPerLdgA_,
- /// The number of scalars per STS for A.
- kScalarsPerLdgA_,
- /// The number of scalars per LDS for A.
- 2,
- /// The number of scalars per LDG for B.
- kScalarsPerLdgB_,
- /// The number of scalars per STS for B.
- kScalarsPerLdgB_,
- /// The number of scalars per LDS for B.
- 2,
- /// The number of scalars per LDG for C and STG for D.
- 1,
- /// The number of scalars per STS for D.
- 2,
- /// The number of scalars per LDS for D.
- 1,
- /// The number of stages in shared memory.
- 2> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The output tile.
- typename OutputTile_ = Shape<8, 64, 128>,
- /// The functor to use in the epilogue.
- typename EpilogueFunctor_ = LinearScaling<double>,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_ = Shape<8, 8, 8>,
- /// The number of doubles loaded in one LDG for A.
- int kScalarsPerLdgA_ = 1,
- /// The number of doubles loaded in one LDG for B.
- int kScalarsPerLdgB_ = 1,
- /// The index.
- typename Index_ = int,
- /// The DGEMM config.
- typename GemmConfig_ =
- DgemmConfig<OutputTile_, AccumulatorsPerThread_, kScalarsPerLdgA_, kScalarsPerLdgB_>,
- /// The traits class for the epilogue.
- typename GemmEpilogueTraits_ =
- SimplifiedGemmEpilogueTraits<GemmConfig_, EpilogueFunctor_, Index_> >
-struct DgemmTraits : public SimplifiedGemmTraits<
- // The layout for A.
- kLayoutA_,
- // The layout for B.
- kLayoutB_,
- // The config.
- GemmConfig_,
- // The epilogue.
- GemmEpilogue<GemmEpilogueTraits_>,
- // The index.
- Index_> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm.h b/cutlass-example/cutlass/gemm/gemm.h
deleted file mode 100644
index c50a3f0..0000000
--- a/cutlass-example/cutlass/gemm/gemm.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Implements a software-pipelined efficient GEMM.
-*/
-#pragma once
-
-#if !defined(__CUDACC_RTC__)
-#include <cuda.h>
-#endif
-
-#include <cutlass/coord.h>
-#include <cutlass/util/platform.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Gemm_>
-__global__ /*__launch_bounds__(Gemm_::kThreads)*/ void gemm_kernel(typename Gemm_::Params params) {
- // Declare shared memory.
- __shared__ typename Gemm_::SharedStorage shared_storage;
-
- // Construct the GEMM object.
- Gemm_ gemm(params, shared_storage);
- // Run GEMM.
- gemm.multiply_add();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, typename Index_ = int>
-struct GemmDesc {
- /// The dimensions of the GEMM.
- Index_ m, n, k;
- /// The alpha/beta scaling values.
- Scalar_ alpha, beta;
- /// The source matrix A.
- void const* d_a;
- /// The stride for A.
- Index_ lda;
- /// The source matrix B.
- void const* d_b;
- /// The stride for B.
- Index_ ldb;
- /// The source matrix C.
- void const* d_c;
- /// The stride for C.
- Index_ ldc;
- /// The destination matrix D.
- void* d_d;
- /// The stride for D.
- Index_ ldd;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmTraits_>
-struct Gemm {
- /// This class.
- typedef Gemm<GemmTraits_> This_;
- /// The traits.
- typedef GemmTraits_ Traits;
- /// The shared storage.
- typedef typename Traits::SharedStorage SharedStorage;
-
- /// The scalar for A.
- typedef typename Traits::ScalarA ScalarA;
- /// The scalar for B.
- typedef typename Traits::ScalarB ScalarB;
- /// The scalar in the epilogue.
- typedef typename Traits::Epilogue::Scalar ScalarEpilogue;
- /// The scalar for C.
- typedef typename Traits::Epilogue::ScalarC ScalarC;
- /// The scalar for D.
- typedef typename Traits::Epilogue::ScalarD ScalarD;
- /// The index.
- typedef typename Traits::Index Index;
-
- /// The number of threads.
- static int const kThreads = Traits::GemmConfig::kThreads;
-
- /// The params.
- struct Params : public Traits::Params {
- CUTLASS_HOST_DEVICE int initialize(Index m,
- Index n,
- Index k,
- ScalarEpilogue alpha,
- ScalarA const* d_a,
- Index lda,
- ScalarB const* d_b,
- Index ldb,
- ScalarEpilogue beta,
- ScalarC const* d_c,
- Index ldc,
- ScalarD* d_d,
- Index ldd) {
- GemmDesc<ScalarEpilogue, Index> desc;
- desc.m = m;
- desc.n = n;
- desc.k = k;
- desc.alpha = alpha;
- desc.beta = beta;
- desc.d_a = reinterpret_cast<void const*>(d_a);
- desc.lda = lda;
- desc.d_b = reinterpret_cast<void const*>(d_b);
- desc.ldb = ldb;
- desc.d_c = reinterpret_cast<void const*>(d_c);
- desc.ldc = ldc;
- desc.d_d = reinterpret_cast<void*>(d_d);
- desc.ldd = ldd;
- return Traits::Params::initialize(desc);
- }
- };
-
-#if !defined(__CUDACC_RTC__)
- /// Launch the kernel.
- static __host__ cudaError_t launch(Params const& params,
- cudaStream_t stream = cudaStreamDefault) {
- // Setup the grid.
- dim3 grid;
- grid.x = (params.m + Traits::OutputTile::kW - 1) / Traits::OutputTile::kW;
- grid.y = (params.n + Traits::OutputTile::kH - 1) / Traits::OutputTile::kH;
-
- // The number of threads.
- dim3 block;
- block.x = kThreads;
-
- // Launch the kernel.
- void const* params_ = reinterpret_cast<void const*>(&params);
-
- return cudaLaunchKernel(reinterpret_cast<void*>(&gemm_kernel<This_>),
- grid,
- block,
- const_cast<void**>(&params_),
- 0,
- stream);
- }
-
- /// Launch the kernel.
- static __host__ cudaError_t launch(CUfunction kernel,
- Params const& params,
- CUstream stream = CU_STREAM_LEGACY) {
- // Setup the grid.
- dim3 grid;
- grid.x = (params.m + Traits::OutputTile::kW - 1) / Traits::OutputTile::kW;
- grid.y = (params.n + Traits::OutputTile::kH - 1) / Traits::OutputTile::kH;
-
- // The number of threads.
- dim3 block;
- block.x = kThreads;
-
- // Launch the kernel.
- void* params_[] = {const_cast<void*>(reinterpret_cast<void const*>(&params))};
-
- // return cudaLaunchKernel(reinterpret_cast<void*>(&gemm_kernel<This_>), grid, block,
- // const_cast<void**>(&params_), 0, stream);
- CUresult result = cuLaunchKernel(
- kernel, grid.x, grid.y, grid.z, block.x, block.y, block.z, 0, stream, params_, 0);
-
- if (result != CUDA_SUCCESS) {
- return cudaErrorLaunchFailure;
- }
- return cudaSuccess;
- }
-
-#endif
-
- /// Ctor.
- CUTLASS_DEVICE Gemm(Params const& params_, SharedStorage& shared_storage_)
- : params(params_), shared_storage(shared_storage_) {}
-
- /// Consume a single iteration of the loop.
- template <bool kIsLastIteration>
- CUTLASS_DEVICE void consume_tile(typename Traits::GlobalLoadStream& global_stream,
- typename Traits::SharedLoadStream& shared_load_stream,
- typename Traits::MultiplyAdd::Accumulators& accumulators,
- Index outer_k) {
- // If that's the last "load iteration" update the predicates.
- if (!kIsLastIteration) {
- global_stream.move_to_residue<false>(outer_k);
- }
-
- // Load data for the next iteration of the main loop.
- if (!kIsLastIteration) {
- global_stream.copy();
- }
-
- // The unrolling steps for the main loop.
- int const kUnrollingSteps =
- Traits::MultiplyAdd::AccumulatorsPerWarp::kD / Traits::MultiplyAdd::InstructionShape::kD;
-
- CUTLASS_PRAGMA_UNROLL
- for (int step = 0; step < kUnrollingSteps - 1; ++step) {
- // Trigger the copy from shared memory for the next A/B values.
- shared_load_stream.copy(step + 1);
- // Make sure the values are available for the current iteration to do the multiply-add.
- shared_load_stream.commit(step);
-
- // Do the math on the fragments of the current iteration.
- typename Traits::MultiplyAdd multiply_add;
- multiply_add.multiply_add(shared_load_stream.fragment_a(step),
- shared_load_stream.fragment_b(step),
- accumulators,
- accumulators);
- }
-
- // Make sure the data from shared memory has been entirely consumed.
- Traits::shared_load_fence(true);
-
- // Commit the data in shared memory for A/B.
- if (!kIsLastIteration) {
- global_stream.commit();
- }
-
- // Make sure the data is in shared memory.
- Traits::shared_store_fence(true);
-
- // Trigger the loads for the next iteration (if needed).
- if (!kIsLastIteration) {
- // Move to the next stage for the load (if it makes sense).
- shared_load_stream.inc_stage();
- // Trigger the copy from shared memory for the next loop iteration.
- shared_load_stream.copy(0);
- }
-
- // Make sure the values are available for the current iteration to do the multiply-add.
- shared_load_stream.commit(kUnrollingSteps - 1);
-
- // Do the math on the fragments of the current iteration.
- typename Traits::MultiplyAdd multiply_add;
- multiply_add.multiply_add(shared_load_stream.fragment_a(kUnrollingSteps - 1),
- shared_load_stream.fragment_b(kUnrollingSteps - 1),
- accumulators,
- accumulators);
- }
-
- /// Do the GEMM.
- CUTLASS_DEVICE void multiply_add() {
- // Swizzle the IDs of the block (to enable better cache behavior).
- typename Traits::BlockSwizzle block_swizzle;
- dim3 block = block_swizzle.swizzle();
-
- // Scale the id.
- block.x *= Traits::OutputTile::kW;
- block.y *= Traits::OutputTile::kH;
-
- // We may want to use shared memory to clear the registers.
- typedef typename Traits::ClearAccumulators ClearAccumulators;
-
- // The streams to read A/B from global memory to shared memory.
- typename Traits::GlobalLoadStream global_stream(params, shared_storage, block);
-
- // Create the accumulator clear.
- ClearAccumulators clear(shared_storage.main_loop.clear);
-
- // By how much we unroll the main loop.
- Index const kUnroll = static_cast<Index>(Traits::OutputTile::kD);
-
- // If we do not have enough steps in the main loop, trigger the residue code.
- global_stream.move_to_residue<true>(params.k);
-
- // Fetch the fragments for A and B from global memory.
- global_stream.copy();
-
- // Copy the elements to shared memory (after transformation if needed).
- global_stream.commit();
-
- // Make sure the data is in shared memory.
- Traits::shared_store_fence(false);
-
- // Rollback to the beginning of the GEMM-K dimension. It may have no impact.
- global_stream.rollback();
-
- // The unrolling steps for the main loop.
- int const kUnrollingSteps =
- Traits::MultiplyAdd::AccumulatorsPerWarp::kD / Traits::MultiplyAdd::InstructionShape::kD;
-
- // Make sure we have at least 2 unrolling steps or our pipeling is not going to work.
- static_assert(kUnrollingSteps >= 2, "The pipelining assumes at least two steps");
-
- // The stream of data from shared memory to fragments.
- typename Traits::SharedLoadStream shared_load_stream(params, shared_storage);
-
- // Trigger the copy from shared memory for the 1st stream.
- shared_load_stream.copy(0);
-
- // Allocate the accumulators.
- typename Traits::MultiplyAdd::Accumulators accumulators;
- // Clear the accumulators.
- clear.clear(accumulators);
-
- // The loop index.
- Index outer_k = params.k - kUnroll;
-
- // Enter the main loop and iterate.
- for (; outer_k > 0; outer_k -= kUnroll) {
- consume_tile<false>(global_stream, shared_load_stream, accumulators, outer_k);
- }
-
- // Residual loop.
- for (; outer_k > -kUnroll; outer_k -= kUnroll) {
- consume_tile<true>(global_stream, shared_load_stream, accumulators, outer_k);
- }
-
- // Epilogue.
- typedef typename Traits::Epilogue Epilogue;
- Epilogue epilogue(params.epilogue, shared_storage.epilogue, params.m, params.n);
- epilogue.epilogue(cutlass::make_Coord(0, block.y, block.x), accumulators);
- }
-
- /// The params.
- Params const& params;
- /// The shared storage.
- SharedStorage& shared_storage;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm_epilogue.h b/cutlass-example/cutlass/gemm/gemm_epilogue.h
deleted file mode 100644
index bc25307..0000000
--- a/cutlass-example/cutlass/gemm/gemm_epilogue.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Implements the epilogue phase of the GEMM kernel that efficiently updates global memory
- with
- the computed matrix product.
-*/
-#pragma once
-
-#include <cutlass/convert.h>
-#include <cutlass/coord.h>
-#include <cutlass/fragment.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-CUTLASS_DEVICE bool is_zero(T x) {
- return x == T(0);
-}
-
-#if !defined(__CUDACC_RTC__) || defined(CUTLASS_NVRTC_HAS_FP16)
-CUTLASS_DEVICE bool is_zero(half x) { return reinterpret_cast<int16_t&>(x) == int16_t(0); }
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmEpilogueTraits_>
-struct GemmEpilogue {
- /// The traits class.
- typedef GemmEpilogueTraits_ Traits;
- /// The params.
- typedef typename Traits::Params Params;
- /// The shared storage.
- typedef typename Traits::SharedStorage SharedStorage;
-
- /// The output tile.
- typedef typename Traits::OutputTile OutputTile;
- /// The number of iterations.
- typedef typename Traits::Iterations Iterations;
- /// The accumulators.
- typedef typename Traits::Accumulators Accumulators;
- /// The scalar.
- typedef typename Traits::Scalar Scalar;
- /// The functor in charge of the math.
- typedef typename Traits::Functor Functor;
-
- /// We do not support 3D or 4D shapes.
- static_assert(Iterations::kD == 1 && Iterations::kC == 1, "Unsupported 3D/4D shapes");
-
- /// The iterator for C in global memory.
- typedef typename Traits::GlobalLoadIteratorC GlobalLoadIteratorC;
- /// The transformer for C.
- typedef typename Traits::GlobalTransformerC GlobalTransformerC;
- /// The transformer for D.
- typedef typename Traits::GlobalTransformerD GlobalTransformerD;
- /// The iterator for D in global memory.
- typedef typename Traits::GlobalStoreIteratorD GlobalStoreIteratorD;
- /// The iterator to store D in shared memory.
- typedef typename Traits::SharedStoreIteratorD SharedStoreIteratorD;
- /// The shared store transformer for D.
- typedef typename Traits::SharedStoreTransformerD SharedStoreTransformerD;
- /// The iterator to load D in shared memory.
- typedef typename Traits::SharedLoadIteratorD SharedLoadIteratorD;
- /// The shared load transformer for D.
- typedef Copy<typename SharedLoadIteratorD::Fragment> SharedLoadTransformerD;
-
- /// The index.
- typedef typename Traits::Index Index;
-
- /// The scalar for C.
- typedef typename GlobalLoadIteratorC::Scalar ScalarC;
- /// The scalar for D.
- typedef typename GlobalStoreIteratorD::Scalar ScalarD;
-
- /// Ctor.
- CUTLASS_DEVICE GemmEpilogue(Params const& params_,
- SharedStorage& shared_storage_,
- Index m_,
- Index n_)
- : params(params_), shared_storage(shared_storage_), m(m_), n(n_) {}
-
- /// Execute the epilogue.
- CUTLASS_DEVICE void epilogue(Coord<3> const& block, Accumulators& accumulators) {
- if (is_zero(params.functor.beta)) {
- epilogue_with_or_without_beta<true>(block, accumulators);
- } else {
- epilogue_with_or_without_beta<false>(block, accumulators);
- }
- }
-
- template <bool kBetaIsZero_>
- CUTLASS_DEVICE void epilogue_with_or_without_beta(Coord<3> const& block,
- Accumulators& accumulators) {
-
- // The problem size.
- Coord<3> const bounds = cutlass::make_Coord(0, n, m);
-
- // The functor.
- Functor functor(params.functor);
- // The C fragment.
- typename GlobalLoadIteratorC::Fragment fragment_c;
- // The transformed C fragment.
- typename GlobalTransformerC::OutputFragment transformed_c;
-
- CUTLASS_PRAGMA_UNROLL
- for (int h = 0; h < Iterations::kH; ++h) {
- // Compute pointer and predicate offsets for C and D global iterators.
- int const pointer_offset =
- ((params.iterator_d.inc_h * (GlobalStoreIteratorD::Iterations::kH - 1) +
- params.iterator_d.inc_advance) *
- Iterations::kW +
- params.stride_h) *
- h;
- int const predicate_offset =
- ((params.iterator_d.predicate_inc_h * (GlobalStoreIteratorD::Iterations::kH - 1) +
- params.iterator_d.predicate_inc_advance) *
- Iterations::kW +
- Traits::Delta::kH) *
- h;
-
- // The iterator to load the elements of the C matrix.
- GlobalLoadIteratorC global_load_iterator(
- params.iterator_c, bounds, block, pointer_offset, predicate_offset);
- // The transformer for C.
- GlobalTransformerC transformer_c;
- // The transformer for D.
- GlobalTransformerD transformer_d;
- // The iterator to store into the D matrix.
- GlobalStoreIteratorD global_store_iterator(
- params.iterator_d, bounds, block, pointer_offset, predicate_offset);
-
- // The transformer to transform before storing to shared memory.
- SharedStoreTransformerD shared_store_transformer;
- typename SharedStoreTransformerD::OutputFragment shared_store_transformed_d;
-
- // The iterator to store to shared memory.
- SharedStoreIteratorD shared_store_iterator(params.shared_store_iterator_d,
- shared_storage.shared_stream.store);
-
- // The iterator to load from shared memory. TODO: Use a stream.
- SharedLoadIteratorD shared_load_iterator(params.shared_load_iterator_d,
- shared_storage.shared_stream.load);
-
- CUTLASS_PRAGMA_UNROLL
- for (int w = 0; w < Iterations::kW; ++w) {
- // Load the C matrix into fragment.
- if (!kBetaIsZero_) {
- iterator_load(global_load_iterator, fragment_c);
- }
-
- // Make sure we can write to shared memory.
- shared_load_fence();
-
- // Copy the accumulators to shared memory.
- int const offset = (h * Iterations::kW + w) * SharedStoreIteratorD::Fragment::kElements;
-
- shared_store_transformer.transform(accumulators, offset, shared_store_transformed_d);
- shared_iterator_store(shared_store_iterator, shared_store_transformed_d);
-
- // Make sure the data is in shared memory.
- shared_store_fence();
-
- // Copy the accumulators back to registers from shared memory.
- typename SharedLoadIteratorD::Fragment fetched_d;
- shared_iterator_load(shared_load_iterator, fetched_d);
-
- // Do the math.
- typename GlobalTransformerD::InputFragment fragment_d;
-
- if (kBetaIsZero_) {
- functor.evaluate(fetched_d, fragment_d);
- } else {
- // Transform C fragment.
- transformer_c.transform(fragment_c, transformed_c);
- // Do the math.
- functor.evaluate(fetched_d, transformed_c, fragment_d);
- }
-
- // Transform D fragment.
- typename GlobalTransformerD::OutputFragment transformed_d;
- transformer_d.transform(fragment_d, transformed_d);
-
- // Copy the results to global memory.
- iterator_store(global_store_iterator, transformed_d);
- }
- }
- }
-
- /// The memory fence for shared loads.
- CUTLASS_DEVICE void shared_load_fence() { __syncthreads(); }
-
- /// The memory fence for shared stores.
- CUTLASS_DEVICE void shared_store_fence() { __syncthreads(); }
-
- /// The params.
- Params const& params;
- /// The shared storage.
- SharedStorage& shared_storage;
- /// The dimensions of the GEMM.
- Index m, n;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm_epilogue_traits.h b/cutlass-example/cutlass/gemm/gemm_epilogue_traits.h
deleted file mode 100644
index c06fc25..0000000
--- a/cutlass-example/cutlass/gemm/gemm_epilogue_traits.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines structural properties of the GEMM epilogue.
-*/
-#pragma once
-
-#include <cutlass/convert.h>
-#include <cutlass/coord.h>
-#include <cutlass/gemm/gemm_global_stream.h>
-#include <cutlass/gemm/gemm_shared_stream.h>
-#include <cutlass/gemm/linear_scaling.h>
-#include <cutlass/reshape_tile.h>
-#include <cutlass/tile_iterator.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The output tile.
- typename OutputTile_,
- /// The accumulators.
- typename Accumulators_,
- /// The iterator to load C from global memory.
- typename GlobalLoadIteratorC_,
- /// The transformer for C.
- typename GlobalTransformerC_,
- /// The transformer for D.
- typename GlobalTransformerD_,
- /// The iterator to store D to global memory.
- typename GlobalStoreIteratorD_,
- /// The iterator to store D to shared memory.
- typename SharedStoreIteratorD_,
- /// The shared store transformer for D.
- typename SharedStoreTransformerD_,
- /// The iterator to load D from shared memory.
- typename SharedLoadIteratorD_,
- /// The number of iterations in the epilogue.
- typename Iterations_,
- /// The iterations strides.
- typename Delta_,
- /// The functor to be used in the epilogue.
- typename Functor_,
- /// The index.
- typename Index_ = int>
-struct GemmEpilogueTraits {
- //
- /// The output tile.
- typedef OutputTile_ OutputTile;
- /// The number of iterations.
- /// The accumulators.
- typedef Accumulators_ Accumulators;
- /// The iterator for C in global memory.
- typedef GlobalLoadIteratorC_ GlobalLoadIteratorC;
- /// The transformer for C.
- typedef GlobalTransformerC_ GlobalTransformerC;
- /// The transformer for D.
- typedef GlobalTransformerD_ GlobalTransformerD;
- /// The iterator for D in global memory.
- typedef GlobalStoreIteratorD_ GlobalStoreIteratorD;
- /// The iterator to store D in shared memory.
- typedef SharedStoreIteratorD_ SharedStoreIteratorD;
- /// The shared store transformer for D.
- typedef SharedStoreTransformerD_ SharedStoreTransformerD;
- /// The iterator to store D in shared memory.
- typedef SharedLoadIteratorD_ SharedLoadIteratorD;
- /// typedef typename GemmConfig::EpilogueIterations Iterations;
- typedef Iterations_ Iterations;
- /// The iterations strides.
- typedef Delta_ Delta;
-
- /// The functor in charge of the math.
- typedef Functor_ Functor;
- /// The index.
- typedef Index_ Index;
-
- /// We do not support 3D or 4D shapes.
- static_assert(Iterations::kD == 1 && Iterations::kC == 1, "Unsupported 3D/4D shapes");
-
- /// The scalar.
- typedef typename Functor::Scalar Scalar;
- /// The scalar for C.
- typedef typename GlobalLoadIteratorC::Scalar ScalarC;
- /// The scalar for D.
- typedef typename GlobalStoreIteratorD::Scalar ScalarD;
-
- /// The params.
- struct Params {
- /// The strides for H and W in the different iterations of the epilogue.
- Index stride_h, stride_w;
- /// The params for the C iterator.
- typename GlobalLoadIteratorC::Params iterator_c;
- /// The params for the D global iterator.
- typename GlobalStoreIteratorD::Params iterator_d;
- /// The params for the D shared store iterator.
- typename SharedStoreIteratorD::Params shared_store_iterator_d;
- /// The params for the D shared load iterator.
- typename SharedLoadIteratorD::Params shared_load_iterator_d;
- /// The functor params.
- typename Functor::Params functor;
-
- /// Setup the params.
- template <typename GemmDesc_>
- CUTLASS_HOST_DEVICE int initialize(GemmDesc_ const& desc) {
- // The parameters for the functor.
- int error_code = functor.initialize(desc);
- if (error_code) {
- return error_code;
- }
-
- // At the end of the H iteration, we jump over a number of columns.
- this->stride_h = desc.ldd * Delta::kH;
- // Nothing to do here.
- this->stride_w = 0;
-
- // Setup the params for the global memory iterator for C.
- error_code = iterator_c.initialize(
- reinterpret_cast<ScalarC const*>(desc.d_c), desc.ldc, desc.n, stride_w, Delta::kW);
- if (error_code) {
- return error_code;
- }
-
- // Setup the params for the global memory iterator for D.
- return iterator_d.initialize(
- reinterpret_cast<ScalarD*>(desc.d_d), desc.ldd, desc.n, stride_w, Delta::kW);
- }
- };
-
- /// The shared memory storage to exchange data.
- union StreamSharedStorage {
- // The storage for the store iterator.
- typename SharedStoreIteratorD::SharedStorage store;
- // The storage for the store iterator.
- typename SharedLoadIteratorD::SharedStorage load;
- };
-
- /// The shared memory to swizzle the data in the epilogue.
- struct SharedStorage {
- // The storage for the shared stream D.
- StreamSharedStorage shared_stream;
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_, typename EpilogueFunctor_, typename Index_ = int>
-struct GemmEpilogueTraitsHelper {
- /// The scalar.
- typedef typename EpilogueFunctor_::Scalar Scalar;
- /// The output tile.
- typedef typename GemmConfig_::OutputTile OutputTile;
-
- /// The number of iterations in the epilogue.
- typedef Shape<1,
- GemmConfig_::MultiplyAdd::AccumulatorsPerThread::kH /
- GemmConfig_::kAccumulatorsPerLdsB,
- GemmConfig_::kAccumulatorsPerLdsB>
- Iterations;
- // The iteration strides in the H/W dimension.
- typedef Shape<0,
- GemmConfig_::kAccumulatorsPerLdsB*(
- GemmConfig_::Warps::kH* GemmConfig_::MultiplyAdd::ThreadsPerWarp::kH - 1),
- 0>
- Delta;
- /// The functor to do the math in the epilogue.
- typedef EpilogueFunctor_ Functor;
-
- /// The traits class to build the iterator to store to shared memory for D.
- typedef GemmSharedStoreTileDTraits<
- // The pointer is float.
- typename Functor::Scalar,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The number of scalars per STS.
- GemmConfig_::kScalarsPerStsD,
- // The skew -- 128 / sizeof(ScalarD) / kScalarsPerStsD is the number of threads involved in
- // a single STS. We divide by 2 as our objective is to add a skew to the odd threads to
- // avoid bank conflicts between odd and even threads.
- 128 / sizeof(typename GemmConfig_::ScalarD) / GemmConfig_::kScalarsPerStsD / 2 *
- GemmConfig_::kScalarsPerStsD>
- SharedStoreTileTraits;
-
- /// The iterator to store D to shared memory.
- typedef TileStoreIterator<SharedStoreTileTraits,
- typename SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorD;
-
- /// The shared store transformer for D.
- typedef Copy<typename SharedStoreIteratorD::Fragment> SharedStoreTransformerD;
-
- /// The traits class to build the iterator to load from shared memory for D.
- typedef GemmSharedLoadTileDTraits<
- // The pointer is float.
- typename Functor::Scalar,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The number of columns of the output tile written by iteration.
- GemmConfig_::OutputTile::kH / ShapeCount<Iterations>::kCount,
- // The number of scalars per LDS.
- GemmConfig_::kScalarsPerLdsD,
- // The skew.
- SharedStoreTileTraits::kSkew>
- SharedLoadTileTraits;
-
- /// The iterator to load D from shared memory.
- typedef TileLoadIterator<SharedLoadTileTraits,
- typename SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorD;
-
- /// The traits class to build the iterator to load data from global memory for C^N.
- typedef GemmGlobalTileCdTraits<
- // The pointer is float const.
- typename GemmConfig_::ScalarC const,
- // The tile has size (N / Iterations)xM in GEMM's terminology.
- Shape<1,
- GemmConfig_::OutputTile::kH / ShapeCount<Iterations>::kCount,
- GemmConfig_::OutputTile::kW>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // How many elements do we jump over at each iteration?
- Iterations::kW,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgC>
- GlobalLoadTileTraits;
-
- /// The iterator to load C.
- typedef GemmGlobalIteratorCd<GlobalLoadTileTraits, Index_> GlobalLoadIteratorC;
- /// The transformer for C.
- typedef Copy<typename GlobalLoadIteratorC::Fragment> GlobalTransformerC;
-
- /// The traits class to build the iterator to store data to global memory for D^N.
- typedef GemmGlobalTileCdTraits<
- // The pointer is float.
- typename GemmConfig_::ScalarD,
- // The tile has size (N / Iterations)xM in GEMM's terminology.
- Shape<1,
- GemmConfig_::OutputTile::kH / ShapeCount<Iterations>::kCount,
- GemmConfig_::OutputTile::kW>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // How many elements do we jump over at each iteration?
- Iterations::kW,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerStgD>
- GlobalStoreTileTraits;
-
- /// The iterator to store D.
- typedef GemmGlobalIteratorCd<GlobalStoreTileTraits, Index_> GlobalStoreIteratorD;
- /// The transformer for D.
- typedef Copy<typename GlobalStoreIteratorD::Fragment> GlobalTransformerD;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The GEMM config.
- typename GemmConfig_,
- /// The epilogue functor to do the math in the epilogue.
- typename EpilogueFunctor_,
- /// The index.
- typename Index_ = int,
- /// The helper to create the traits class.
- typename Helper_ = GemmEpilogueTraitsHelper<GemmConfig_, EpilogueFunctor_, Index_> >
-struct SimplifiedGemmEpilogueTraits : public GemmEpilogueTraits<
- // The output tile.
- typename GemmConfig_::OutputTile,
- // The accumulators.
- typename GemmConfig_::Accumulators,
- // The global iterator for C.
- typename Helper_::GlobalLoadIteratorC,
- // The transformer for C.
- typename Helper_::GlobalTransformerC,
- // The transformer for D.
- typename Helper_::GlobalTransformerD,
- // The global iterator for D.
- typename Helper_::GlobalStoreIteratorD,
- // The iterator to store D to shared memory.
- typename Helper_::SharedStoreIteratorD,
- // The shared store transformer for D.
- typename Helper_::SharedStoreTransformerD,
- // The iterator to load D from shared memory.
- typename Helper_::SharedLoadIteratorD,
- // The number of iterations.
- typename Helper_::Iterations,
- // The strides between iterations.
- typename Helper_::Delta,
- // The functor to be used in the epilogue.
- EpilogueFunctor_,
- // The index.
- Index_> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm_global_stream.h b/cutlass-example/cutlass/gemm/gemm_global_stream.h
deleted file mode 100644
index ec675a3..0000000
--- a/cutlass-example/cutlass/gemm/gemm_global_stream.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Implements efficient loading of the thread block-level tile from global memory and
- storing
- to shared memory.
-*/
-#pragma once
-
-#include <cutlass/convert.h>
-#include <cutlass/gemm/gemm_global_tile.h>
-#include <cutlass/iterator_access.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The load iterator.
- typename LoadIterator_,
- /// The store iterator to copy to shared memory.
- typename StoreIterator_,
- /// The transformer to be applied after the data has been copied from global memory.
- typename Transformer_>
-
-struct GlobalLoadStreamBase {
- /// The load iterator.
- typedef LoadIterator_ LoadIterator;
- /// The transformer.
- typedef Transformer_ Transformer;
- /// The store iterator to write to shared memory.
- typedef StoreIterator_ StoreIterator;
-
- /// The fragment that is copied from shared memory.
- typedef typename LoadIterator::Fragment FetchedFragment;
- /// The fragment that is obtained after the transformation by the transformer.
- typedef typename Transformer::OutputFragment TransformedFragment;
- /// Make sure the fragments match.
- static_assert((platform::is_same<FetchedFragment, typename Transformer::InputFragment>::value),
- "");
- /// The output fragment.
- typedef TransformedFragment Fragment;
- /// Make sure the transformed fragment is the same as the store fragment.
- static_assert((platform::is_same<TransformedFragment, typename StoreIterator::Fragment>::value),
- "");
-
- /// The layout.
- static MatrixLayout::Kind const kLayout = LoadIterator::kLayout;
- /// The scalar type of the iterator.
- typedef typename LoadIterator::Scalar Scalar;
- /// The pointer.
- typedef typename LoadIterator::Pointer Pointer;
- /// The index.
- typedef typename LoadIterator::Index Index;
-
- /// The params.
- struct Params {
- // The load iterator.
- typename LoadIterator::Params load_iterator;
- // The store iterator.
- typename StoreIterator::Params store_iterator;
-
- /// Setup the params.
- template <typename GemmDesc_>
- CUTLASS_HOST_DEVICE int initialize(GemmDesc_ const& desc, Pointer pointer, Index ld) {
- int error_code = load_iterator.initialize(desc, pointer, ld);
- if (error_code) {
- return error_code;
- }
-
- return store_iterator.initialize();
- }
- };
-
- /// The amount of storage in shared memory needed to store the tile.
- typedef typename StoreIterator::SharedStorage SharedStoreStorage;
-
- /// The storage in shared memory needed by that stream.
- union SharedStorage {
- // The load iterator.
- typename LoadIterator::SharedStorage load_iterator;
- // The store iterator.
- SharedStoreStorage store_iterator;
- };
-
- /// Ctor.
- CUTLASS_DEVICE GlobalLoadStreamBase(Params const& params,
- SharedStorage& shared_storage,
- Coord<3> const bounds,
- Coord<3> const& block)
- : load_iterator(params.load_iterator, bounds, block),
- transformer(),
- store_iterator(params.store_iterator, shared_storage.store_iterator)
-
- {
- fetched_fragment.clear();
- }
-
- /// Load the data from shared memory to the fetch fragment.
- CUTLASS_DEVICE void copy() { iterator_load(load_iterator, fetched_fragment); }
-
- /// Commit the data.
- CUTLASS_DEVICE void commit() {
- transformer.transform(fetched_fragment, transformed_fragment);
- iterator_store(store_iterator, transformed_fragment);
- store_iterator.inc_stage();
- }
-
- /// Move to the beginning of the residue code. That's a new code path in CUTLASS 1.0.1.
- CUTLASS_DEVICE void move_to_residue(Index k) { load_iterator.move_to_residue(k); }
-
- /// Execute the residue code.
- CUTLASS_DEVICE void residue(Index k, bool skip_clear = false) {
- load_iterator.residue(k);
- if (!skip_clear) {
- fetched_fragment.clear();
- }
- }
-
- /// Rollback to the beginning of the GEMM-k dimension.
- CUTLASS_DEVICE void rollback() { load_iterator.rollback(); }
-
- /// The iterator.
- LoadIterator load_iterator;
- /// The fragment to fetch from shared memory.
- FetchedFragment fetched_fragment;
- /// The transformer.
- Transformer transformer;
- /// The fragment to convert the data after it has been fetched from shared memory.
- TransformedFragment transformed_fragment;
- /// The store iterator.
- StoreIterator store_iterator;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The load iterator.
- typename LoadIterator_,
- /// The store iterator to copy to shared memory.
- typename StoreIterator_,
- /// The transformer to be applied after the data has been copied from global memory.
- typename Transformer_ = Copy<typename LoadIterator_::Fragment> >
-
-struct GlobalLoadStream : public GlobalLoadStreamBase<LoadIterator_, StoreIterator_, Transformer_> {
- /// The base class.
- typedef GlobalLoadStreamBase<LoadIterator_, StoreIterator_, Transformer_> Base;
-
- /// Ctor.
- CUTLASS_DEVICE GlobalLoadStream(typename Base::Params const& params,
- typename Base::SharedStorage& shared_storage,
- Coord<3> const& bounds,
- Coord<3> const& block)
- : Base(params, shared_storage, bounds, block) {}
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm_global_tile.h b/cutlass-example/cutlass/gemm/gemm_global_tile.h
deleted file mode 100644
index 1cc3b33..0000000
--- a/cutlass-example/cutlass/gemm/gemm_global_tile.h
+++ /dev/null
@@ -1,541 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines iterators for efficiently loading and storing to global memory.
-*/
-#pragma once
-
-#include <cutlass/coord.h>
-#include <cutlass/util/platform.h>
-
-#include <cutlass/gemm/gemm_operand.h>
-#include <cutlass/matrix_traits.h>
-#include <cutlass/predicate_vector.h>
-#include <cutlass/reshape_tile.h>
-#include <cutlass/tile_iterator.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// The following functor reshapes a tile of threads to match a tile of data. The idea is that when
-// the user wants to build the iterator traits, he/she may want to specify the tile independently
-// from the number of scalars loaded/stored per instruction. For example, in the row-major version
-// with a tile of size 128x8 - the user may want to that the iterator works with 32x8 threads if
-// each thread loads 1 scalar per LDG. If the user changes to 4 scalars per LDG, then the tile of
-// threads has to change. The code below detects that and correct the code automatically - it is
-// a helper when the user does not specify the right configuration.
-
-template <typename Tile_, typename Threads_, bool = (Tile_::kW < Threads_::kW)>
-struct ReshapeThreads {
- typedef Threads_ Threads;
-};
-
-template <typename Tile_, typename Threads_>
-struct ReshapeThreads<Tile_, Threads_, true> {
- typedef Shape<Threads_::kD, Threads_::kH * Threads_::kW / Tile_::kW, Tile_::kW, 1> Threads;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <GemmOperand::Kind kOperand_,
- MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename Tile_,
- typename Threads_,
- int kAccessSize_>
-struct GemmGlobalTileTraits {
- /// Identity of the operand
- static GemmOperand::Kind const kOperand = kOperand_;
- /// The layout.
- static MatrixLayout::Kind const kLayout = kLayout_;
- /// The scalar.
- typedef typename platform::remove_const<Scalar_>::type Scalar;
- /// The pointer.
- typedef Scalar_* Pointer;
- /// The number of scalars per LDG/STG.
- static int const kAccessSize = kAccessSize_;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kGlobal;
-
- /// The tile shape
- typedef typename ReshapeTile<Tile_, kAccessSize_>::Tile Tile;
- /// The threads shape
- typedef typename ReshapeThreads<Tile, Threads_>::Threads Threads;
- /// The relative offset between two elements in the H/W dimension in adjacent threads.
- typedef Shape<1, 1, Tile::kC> ThreadsDelta;
-
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, Threads::kH, Threads::kW * kAccessSize> Delta;
- /// Strides for immediate offset computation
- typedef Shape<0, 0, Threads::kW * ThreadsDelta::kW, kAccessSize> ImmediateOffsetStrides;
- /// The number of iterations needed to load/store the tile.
- typedef Shape<1, Tile::kH / Threads::kH, Tile::kW / Threads::kW, Tile::kC / kAccessSize>
- Iterations;
-
- typedef GemmMultiplicandTraits<Tile, kOperand, kLayout> MultiplicandTraits;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- int thread_offset_h = threadIdx.x / Threads::kW * ThreadsDelta::kH;
- int thread_offset_w = threadIdx.x % Threads::kW * ThreadsDelta::kW;
-
- return make_Coord(0, thread_offset_h, thread_offset_w, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, typename Tile_, typename Threads_, int kStrideH_, int kAccessSize_>
-struct GemmGlobalTileCdTraits : public GemmGlobalTileTraits<GemmOperand::kC,
- MatrixLayout::kColumnMajor,
- Scalar_,
- Tile_,
- Threads_,
- kAccessSize_> {
- /// The base class.
- typedef GemmGlobalTileTraits<GemmOperand::kC,
- MatrixLayout::kColumnMajor,
- Scalar_,
- Tile_,
- Threads_,
- kAccessSize_>
- Base;
-
- /// The stride in the H dimension.
- static int const kStrideH = kStrideH_;
- /// Override the strides in each dimension between different loads/stores.
- typedef Shape<0, 0, Base::Delta::kW, Base::Delta::kC> Delta;
-
- typedef typename Base::Iterations Iterations;
-
- typedef typename Base::Threads Threads;
-
- typedef typename Base::ThreadsDelta ThreadsDelta;
-
- typedef typename Base::ImmediateOffsetStrides ImmediateOffsetStrides;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- int thread_offset_h = threadIdx.x / Threads::kW * kStrideH * Iterations::kH;
- int thread_offset_w = threadIdx.x % Threads::kW * ThreadsDelta::kW;
-
- return make_Coord(0, thread_offset_h, thread_offset_w, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename TileTraits_, typename Index_ = int>
-struct GemmGlobalIteratorAb
- : public TileLoadIterator<TileTraits_,
- typename TileTraits_::Scalar,
- TileTraits_::MultiplicandTraits::kKstrided ? IteratorAdvance::kH
- : IteratorAdvance::kW,
- MemorySpace::kGlobal,
- Index_> {
- /// This class.
- typedef GemmGlobalIteratorAb<TileTraits_, Index_> This_; /// The base class.
-
- typedef TileLoadIterator<TileTraits_,
- typename TileTraits_::Scalar,
- TileTraits_::MultiplicandTraits::kKstrided ? IteratorAdvance::kH
- : IteratorAdvance::kW,
- MemorySpace::kGlobal,
- Index_>
- Base;
- /// The layout.
- static MatrixLayout::Kind const kLayout = TileTraits_::kLayout;
- /// Fragment type loaded by the iterator
- typedef typename Base::Fragment Fragment;
- /// The scalar.
- typedef typename TileTraits_::Scalar Scalar;
- /// The threads.
- typedef typename TileTraits_::Threads Threads;
- /// The index.
- typedef Index_ Index;
- /// The thread offset
- typedef typename TileTraits_::ThreadOffset ThreadOffset;
- /// Specifies in which dimension post-increment accesses advance.
- static IteratorAdvance::Kind const kAdvance = Base::kAdvance;
-
- typedef cutlass::PredicateVector<ShapeCount<typename Base::Iterations>::kCount> PredicateVector;
-
- /// Iterator parameters type
- typedef typename Base::Params BaseParams;
-
- struct Params : public BaseParams {
- /// Initializes params to load a strip-mined tile, given pointer and stride_h.
- template <typename GemmDesc_>
- CUTLASS_HOST_DEVICE int initialize(GemmDesc_ const& desc, Scalar const* ptr, Index stride_h) {
- Index inc_d = 0;
- Index inc_advance = 0;
- // Move by some columns for each iteration in the H dimension.
- Index inc_h = Base::Delta::kH * stride_h;
-
- // Move by some more columns in the number of iterations if the D dimension is > 1.
- if (Base::Delta::kD > 0) {
- inc_d = Base::Delta::kD * stride_h - (Base::Iterations::kH - 1) * inc_h;
- }
-
- // Move to the beginning of the next iteration.
- if (kAdvance == IteratorAdvance::kH && Base::Delta::kD > 0) {
- inc_advance = inc_d;
- } else if (kAdvance == IteratorAdvance::kH) {
- inc_advance = inc_h;
- } else if (Base::Delta::kD > 0) {
- inc_advance = (Base::Iterations::kW + 0) * ShapeCount<typename Base::Delta>::kWc -
- (Base::Iterations::kH - 1) * inc_h -
- (Base::Iterations::kD - 1) * Base::Delta::kD * stride_h;
- } else {
- inc_advance = (Base::Iterations::kW + 0) * ShapeCount<typename Base::Delta>::kWc -
- (Base::Iterations::kH - 1) * inc_h;
- }
-
- // The dimensions of the tile.
- int const kH = TileTraits_::Tile::kH;
- int const kW = TileTraits_::Tile::kW * TileTraits_::kAccessSize;
-
- // Move to the residue.
- Index const kBlock = kAdvance == IteratorAdvance::kH ? kH : kW;
- // The jump in the gemm-k dimension.
- Index const stride = kAdvance == IteratorAdvance::kH ? stride_h : 1;
-
- // Compute the offset to the residue and how to "come" back.
- Index const kResidue = desc.k % kBlock;
- if (kResidue > 0) {
- move_to_residue_offset = (desc.k - kResidue) * stride;
- } else {
- move_to_residue_offset = (desc.k - kBlock) * stride;
- }
-
- Base::Params::initialize(ptr, 0, stride_h, 1, inc_d, inc_h, 0, inc_advance);
- return 0;
- }
-
- // The extra offset to control moving to the residue.
- Index move_to_residue_offset;
- };
-
- /// Ctor.
- CUTLASS_DEVICE GemmGlobalIteratorAb(Params const& _params,
- const Coord<3>& bounds,
- const Coord<3>& block,
- ThreadOffset thread_offset_func = ThreadOffset())
- : params(_params) {
- thread_offset = thread_offset_func();
- // The column.
- Index block_h = thread_offset[1];
- // The contiguous dimension.
- Index block_w = thread_offset[2];
-
- // Add the blocks indices.
- if (kAdvance == IteratorAdvance::kH) {
- block_h += block[1];
- block_w += block[2];
-
- } else {
- block_h += block[2];
- block_w += block[1];
- }
-
- // Setup the pointer.
- params.pointer += (block_h * params.stride_h + block_w);
-
- // Initialize predicates
- initialize_predicates(bounds, make_Coord(0, block_h, block_w));
- }
-
- /// The accessor.
- CUTLASS_DEVICE void get(typename Base::AccessType& value, int d, int h, int w, int c) const {
- int const imm =
- ComputeOffsetFromStrides<typename Base::ImmediateOffsetStrides>::get(0, 0, w, c);
- Load<Scalar, TileTraits_::kAccessSize, MemorySpace::kGlobal>::load(value, params.pointer, imm);
- }
-
- /// Increment the pointer in the H dimension.
- CUTLASS_DEVICE void inc_h() { params.pointer += params.inc_h; }
- /// Increment the pointer in the D dimension.
- CUTLASS_DEVICE void inc_d() { params.pointer += params.inc_d; }
- /// Increment the pointer to move to the next iteration.
- CUTLASS_DEVICE void inc_advance() { params.pointer += params.inc_advance; }
-
- /// Initialize the predicates.
- CUTLASS_DEVICE void initialize_predicates(const Coord<3>& bounds, const Coord<3>& block) {
- // Setup the masks to control loads.
- predicates.fill(0);
-
- int bounds_h, bounds_w;
- if (kAdvance == IteratorAdvance::kH) {
- bounds_w = bounds[2] - block[2];
- bounds_h = bounds[1];
-
- } else {
- bounds_w = bounds[1];
- bounds_h = bounds[2] - block[1];
- }
-
- // Fill in the bits of the predicate vector.
- for (int d = 0; d < Base::Iterations::kD; ++d) {
- for (int h = 0; h < Base::Iterations::kH; ++h) {
- for (int w = 0; w < Base::Iterations::kW; ++w) {
- for (int c = 0; c < Base::Iterations::kC; ++c) {
- bool flag = w * Base::Delta::kW < bounds_w;
- if (kAdvance == IteratorAdvance::kH) {
- flag = flag && (h * Base::Delta::kH + d * Base::Delta::kD) < bounds_h;
- } else {
- flag = flag && (h * Base::Delta::kH) < bounds_h;
- }
- int const bit = ComputeOffsetFromShape<typename Base::Iterations>::get(d, h, w, c);
- predicates.set(bit, flag);
- }
- }
- }
- }
- }
-
- /// Move to residue portion.
- CUTLASS_DEVICE void move_to_residue(Index k) {
- // Store the pointer and the predicates.
- stored_pointer = params.pointer;
- stored_predicates = predicates;
-
- // Move the pointer to the residue.
- params.pointer += params.move_to_residue_offset;
-
- // The dimensions of the tile.
- int const kH = TileTraits_::Tile::kH;
- int const kW = TileTraits_::Tile::kW * TileTraits_::kAccessSize;
-
- // The unrolling factor.
- int const kUnroll = kAdvance == IteratorAdvance::kH ? kH : kW;
-
- // Clear the predicates for the residue. TODO: We can do something smarter.
- int const kResidue = (int)(k % (Index)kUnroll);
- if (kResidue > 0) {
- residue(kResidue);
- }
- }
-
- /// That's the residue! Update the predicates.
- CUTLASS_DEVICE void residue(Index k) {
- // The coordinates of the thread.
- Index block_h = thread_offset[1];
- // The contiguous dimension.
- Index block_w = thread_offset[2];
-
- // Update the predicate vector.
- for (int d = 0; d < Base::Iterations::kD; ++d) {
- for (int h = 0; h < Base::Iterations::kH; ++h) {
- for (int w = 0; w < Base::Iterations::kW; ++w) {
- for (int c = 0; c < Base::Iterations::kC; ++c) {
- Index offset = 0;
- if (kAdvance == IteratorAdvance::kH) {
- offset += block_h + h * Base::Delta::kH + d * Base::Delta::kD;
- } else {
- offset += block_w + w * Base::Delta::kW;
- }
-
- int const bit = ComputeOffsetFromShape<typename Base::Iterations>::get(d, h, w, c);
- if (offset >= k) {
- predicates.set(bit, false);
- }
- }
- }
- }
- }
- }
-
- /// Rollback to beginning of first tile and initialize predicates.
- CUTLASS_DEVICE void rollback() {
- params.pointer = stored_pointer;
- predicates = stored_predicates;
- }
-
- /// Is the iterator valid?
- CUTLASS_DEVICE bool valid(int d, int h, int w, int c) const {
- int const bit = ComputeOffsetFromShape<typename Base::Iterations>::get(d, h, w, c);
- return predicates[bit];
- }
-
- /// Offset of an individual lane from the start of the tile
- Coord<4> thread_offset;
- /// The parameters
- Params params;
- /// The pointer.
- typename Base::Scalar const* stored_pointer;
- /// The predicates.
- PredicateVector predicates, stored_predicates;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename TileTraits_, typename Index_ = int>
-struct GemmGlobalIteratorCd : public TileIteratorBase<TileTraits_,
- typename TileTraits_::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kGlobal,
- Index_> {
- /// This class.
- typedef GemmGlobalIteratorCd<TileTraits_, Index_> This_;
- /// The base class.
- typedef TileIteratorBase<TileTraits_,
- typename TileTraits_::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kGlobal,
- Index_>
- Base;
-
- /// The layout.
- static MatrixLayout::Kind const kLayout = TileTraits_::kLayout;
-
- /// The scalar.
- typedef typename TileTraits_::Scalar Scalar;
- /// The pointer.
- typedef typename TileTraits_::Pointer Pointer;
- /// The threads.
- typedef typename TileTraits_::Threads Threads;
- /// The index.
- typedef Index_ Index;
- /// The thread offset
- typedef typename TileTraits_::ThreadOffset ThreadOffset;
-
- /// The params.
- struct Params {
- /// The pointer.
- Pointer pointer;
- /// The stride in the H dimension to setup the thread in the block.
- Index stride_h;
- /// The strides to increment the pointer.
- Index inc_advance, inc_h;
- /// The strides to increment the predicate offset
- Index predicate_inc_advance, predicate_inc_h;
- /// The column offset to compute the predicate for the columns.
- Index predicate_offset;
-
- /// Setup the params.
- CUTLASS_HOST_DEVICE int initialize(
- Pointer pointer, Index ld, Index bound, Index epilogue_stride_w, Index epilogue_delta_w) {
- // The pointer.
- this->pointer = pointer;
- // Each column of the matrix.
- stride_h = TileTraits_::ThreadsDelta::kH * ld;
- // Each thread output 1 column per iteration. The stride between columns is given by the
- // number of scalars that are loaded per LDS for B.
- inc_h = ld * TileTraits_::kStrideH;
- inc_advance =
- (ld - ld * TileTraits_::kStrideH * (Base::Iterations::kH - 1)) + epilogue_stride_w;
-
- predicate_offset = bound;
- predicate_inc_h = TileTraits_::kStrideH;
- predicate_inc_advance =
- -((TileTraits_::kStrideH * (Base::Iterations::kH - 1) - 1) + epilogue_delta_w);
-
- return 0;
- }
- };
-
- Params params;
- /// Offset of an individual lane from the start of the tile
- Coord<4> thread_offset;
-
- /// Ctor.
- CUTLASS_DEVICE GemmGlobalIteratorCd() {}
-
- /// Ctor.
- CUTLASS_DEVICE GemmGlobalIteratorCd(Params const& params,
- const Coord<3>& bounds,
- const Coord<3>& block,
- int offset = 0,
- int pred_offset = 0,
- ThreadOffset thread_offset_func = ThreadOffset())
- : params(params) {
- thread_offset = thread_offset_func();
- // Each warp works on a different column of the tile.
- int const h = thread_offset[1] + block[1];
- // Each lane writes a different element.
- int const w = thread_offset[2] + block[2];
- // Setup the pointer.
- this->params.pointer += ((h * params.stride_h + w) + offset);
-
- // Prepare the vector of predicates.
- for (int i = 0; i < Base::Iterations::kW; ++i) {
- predicates.set(i, w + i * Base::Delta::kW < bounds[2]);
- }
- this->params.predicate_offset -= (h + pred_offset);
- }
-
- /// The accessor.
- CUTLASS_DEVICE void get(typename Base::AccessType& value, int d, int h, int w, int c) const {
- int const imm =
- ComputeOffsetFromStrides<typename Base::ImmediateOffsetStrides>::get(0, 0, w, c);
- Load<Scalar, TileTraits_::kAccessSize, MemorySpace::kGlobal>::load(value, params.pointer, imm);
- }
-
- /// Increment the pointer in the C dimension.
- CUTLASS_DEVICE void inc_c() {}
- /// Increment the pointer in the W dimension.
- CUTLASS_DEVICE void inc_w() {}
- /// Increment the pointer in the H dimension.
- CUTLASS_DEVICE void inc_h() {
- params.pointer += params.inc_h;
- params.predicate_offset -= params.predicate_inc_h;
- }
- /// Increment the pointer in the D dimension.
- CUTLASS_DEVICE void inc_d() {}
- /// Increment the pointer to move to the next iteration.
- CUTLASS_DEVICE void inc_advance() {
- params.pointer += params.inc_advance;
- this->params.predicate_offset -= params.predicate_inc_advance;
- }
-
- /// The accessor.
- CUTLASS_DEVICE void set(typename Base::AccessType const& value, int d, int h, int w, int c) {
- int const imm =
- ComputeOffsetFromStrides<typename Base::ImmediateOffsetStrides>::get(0, 0, w, c);
- Store<Scalar, TileTraits_::kAccessSize, MemorySpace::kGlobal>::store(
- value, params.pointer, imm);
- }
-
- /// Test the validity of the iterator.
- CUTLASS_DEVICE bool valid(int d, int h, int w, int c) const {
- return predicates.at(w) && params.predicate_offset > 0;
- }
-
- /// The predicates for the row.
- cutlass::PredicateVector<Base::Iterations::kW> predicates;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm_operand.h b/cutlass-example/cutlass/gemm/gemm_operand.h
deleted file mode 100644
index 737f993..0000000
--- a/cutlass-example/cutlass/gemm/gemm_operand.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines constant expressions for mapping GEMM problem size and strides onto pitch-linear
- memory.
-*/
-#pragma once
-
-#include <cutlass/matrix_traits.h>
-#include <cutlass/reshape_tile.h>
-#include <cutlass/util/platform.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Helper to describe attributes of GEMM matrix operands
-template <GemmOperand::Kind kOperand_, MatrixLayout::Kind kLayout_>
-struct GemmOperandTraitsAb {
- static const bool Congruous =
- (kOperand_ == GemmOperand::kA ^ kLayout_ == MatrixLayout::kRowMajor);
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmOperand::Kind kOperand_, typename Tile_>
-struct GetExtent;
-
-template <typename Tile_>
-struct GetExtent<GemmOperand::kA, Tile_> {
- static const int kExtent = Tile_::kW;
-};
-
-template <typename Tile_>
-struct GetExtent<GemmOperand::kB, Tile_> {
- static const int kExtent = Tile_::kH;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Determines the shape of a multiplicand tile in terms of strided (H) and contiguous (W)
-/// dimensions
-template <typename ThreadBlockTile_, GemmOperand::Kind Usage, MatrixLayout::Kind Layout>
-struct GemmMultiplicandTraits {
- // Only defined for A or B
- static_assert(Usage == GemmOperand::kA || Usage == GemmOperand::kB,
- "MultiplicandTileShape defined only for A or B operands.");
-
- /// Shape of GEMM thread block tile (K, N, M)
- typedef ThreadBlockTile_ ThreadBlockTile;
-
- /// Identifies multiplicand
- static GemmOperand::Kind const kUsage = Usage;
-
- /// Layout of tile
- static MatrixLayout::Kind const kLayout = Layout;
-
- // True if K is the strided dimension
- static bool const kKstrided = (kUsage == GemmOperand::kA ^ kLayout == MatrixLayout::kRowMajor);
-
- /// Map the ThreadBlockShape onto (kH, kW) dimensions for A and B operand
- typedef typename platform::conditional<
- kKstrided,
- Shape<1, ThreadBlockTile::kD, GetExtent<Usage, ThreadBlockTile>::kExtent>,
- Shape<1, GetExtent<Usage, ThreadBlockTile>::kExtent, ThreadBlockTile::kD> >::type Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Project's a coordinate (K, N, M) onto inner and outer dimensions defined for each
-/// operand.
-template <GemmOperand::Kind operand, bool Kstrided = true>
-struct ProjectOperand;
-
-/// Project A operand - (0, K, M)
-template <bool Kstrided>
-struct ProjectOperand<GemmOperand::kA, Kstrided> {
- CUTLASS_HOST_DEVICE
- static Coord<3> project(Coord<3> const &coord) {
- if (Kstrided) {
- return make_Coord(0, coord[0], coord[2]);
- } else {
- return make_Coord(0, coord[2], coord[0]);
- }
- }
-};
-
-/// Project B operand - (0, K, N)
-template <bool Kstrided>
-struct ProjectOperand<GemmOperand::kB, Kstrided> {
- CUTLASS_HOST_DEVICE
- static Coord<3> project(Coord<3> const &coord) {
- if (Kstrided) {
- return make_Coord(0, coord[0], coord[1]);
- } else {
- return make_Coord(0, coord[1], coord[0]);
- }
- }
-};
-
-/// Project C operand - (0, N, M)
-template <>
-struct ProjectOperand<GemmOperand::kC, true> {
- CUTLASS_HOST_DEVICE
- static Coord<3> project(Coord<3> const &coord) { return make_Coord(0, coord[1], coord[2]); }
-};
-
-/// Project D operand - (0, N, M)
-template <>
-struct ProjectOperand<GemmOperand::kD, true> {
- CUTLASS_HOST_DEVICE
- static Coord<3> project(Coord<3> const &coord) { return make_Coord(0, coord[1], coord[2]); }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm_shared_stream.h b/cutlass-example/cutlass/gemm/gemm_shared_stream.h
deleted file mode 100644
index c6ff7bd..0000000
--- a/cutlass-example/cutlass/gemm/gemm_shared_stream.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines abstractions for managing loading and storing fragments to shared memory in the
- efficient GEMM pipeline.
-*/
-#pragma once
-
-#include <cutlass/gemm/gemm_shared_tile.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The load iterator.
- typename Iterator_,
- /// The transformer to be applied after the data has been copied from shared memory.
- typename Transformer_ = Copy<typename Iterator_::Fragment> >
-
-struct SharedLoadStream {
- /// The load iterator.
- typedef Iterator_ Iterator;
- /// The transformer.
- typedef Transformer_ Transformer;
-
- /// The fragment that is copied from shared memory.
- typedef typename Iterator::Fragment FetchedFragment;
- /// The fragment that is obtained after the transformation by the transformer.
- typedef typename Transformer::OutputFragment TransformedFragment;
- /// Make sure the fragments match.
- static_assert((platform::is_same<FetchedFragment, typename Transformer::InputFragment>::value),
- "");
- /// The output fragment.
- typedef TransformedFragment Fragment;
-
- /// The params.
- struct Params {
- /// The iterator params.
- typename Iterator::Params iterator;
-
- /// Setup the params.
- CUTLASS_HOST_DEVICE int initialize() { return iterator.initialize(); }
- };
-
- /// The storage in shared memory needed by that stream.
- typedef typename Iterator::Storage SharedStorage;
-
- /// Ctor.
- CUTLASS_DEVICE SharedLoadStream() {}
-
- /// Ctor.
- CUTLASS_DEVICE SharedLoadStream(Params const &params, SharedStorage &shared_storage) {
- this->initialize(params, shared_storage);
- }
-
- /// Initialize the stream.
- CUTLASS_DEVICE void initialize(Params const &params, SharedStorage &shared_storage) {
- // The iterator.
- iterator = Iterator(params.iterator, shared_storage);
- // The transformer.
- transformer = Transformer();
- }
-
- /// Load the data from shared memory to the fetch fragment.
- CUTLASS_DEVICE void copy(FetchedFragment &fetched) { shared_iterator_load(iterator, fetched); }
-
- /// Load the data from shared memory to the fetch fragment.
- CUTLASS_DEVICE void copy(int d, FetchedFragment &fetched) {
- shared_iterator_load(iterator, fetched, d);
- }
-
- /// Commit the data.
- CUTLASS_DEVICE void commit(FetchedFragment &fetched, TransformedFragment &transformed) {
- transformer.transform(fetched, transformed);
- }
-
- /// Increment the stage.
- CUTLASS_DEVICE void inc_stage() { iterator.inc_stage(); }
-
- /// The iterator.
- Iterator iterator;
- /// The transformer.
- Transformer transformer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm_shared_tile.h b/cutlass-example/cutlass/gemm/gemm_shared_tile.h
deleted file mode 100644
index 7c61e02..0000000
--- a/cutlass-example/cutlass/gemm/gemm_shared_tile.h
+++ /dev/null
@@ -1,417 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines iterators for efficiently loading and storing tiles to and from shared memory.
-*/
-#pragma once
-
-#include <cutlass/gemm/gemm_operand.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, typename Tile_, typename Threads_, int kScalarsPerSts_>
-struct GemmSharedStoreTileAbTraits {
- /// The scalar.
- typedef typename platform::remove_const<Scalar_>::type Scalar;
- /// The pointer.
- typedef Scalar_* Pointer;
- /// The tile.
- typedef typename ReshapeTile<Tile_, kScalarsPerSts_>::Tile Tile;
- /// The threads.
- typedef Threads_ Threads;
- /// The strides to compute the base position of the thread.
- typedef Shape<0, ShapeCount<Tile>::kWc, Tile::kC, kScalarsPerSts_> ThreadsStrides;
- /// The skew.
- static int const kSkew = 0;
- /// The number of scalars per LDG/STG.
- static int const kAccessSize = kScalarsPerSts_;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
-
- /// The number of iterations needed to load/store the tile.
- typedef Shape<1,
- Tile::kH / Threads::kH,
- Tile::kW / Threads::kW,
- Tile::kC / Threads::kC / kAccessSize>
- Iterations;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, Threads::kH * ShapeCount<Tile>::kWc, Threads::kW * kAccessSize> Delta;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, Threads::kH * ShapeCount<Tile>::kWc, Threads::kW * kAccessSize>
- ImmediateOffsetStrides;
-
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- int offset = ComputeThreadOffsetFromStrides<Threads, ThreadsStrides>::get();
- return make_Coord(0, 0, offset, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, typename Tile_, typename Threads_, int kScalarsPerSts_, int kSkew_>
-struct GemmSharedStoreWithSkewTileAbTraits {
- /// The scalar.
- typedef typename platform::remove_const<Scalar_>::type Scalar;
- /// The pointer.
- typedef Scalar_* Pointer;
- /// The tile without skews.
- typedef typename ReshapeTile<Tile_, kScalarsPerSts_>::Tile TileWithoutSkew;
- /// The tile.
- typedef typename ReshapeTile<Shape<Tile_::kD, Tile_::kH, Tile_::kW + kSkew_>,
- kScalarsPerSts_>::Tile Tile;
- /// The threads.
- typedef Threads_ Threads;
- /// The skew.
- static int const kSkew = kSkew_;
- /// The number of scalars per STS.
- static int const kAccessSize = kScalarsPerSts_;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
-
- /// The number of iterations needed to load/store the tile.
- typedef Shape<1, TileWithoutSkew::kH / Threads::kW, TileWithoutSkew::kW / Threads::kH> Iterations;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, ShapeCount<Tile>::kWc, Threads::kH * kAccessSize> Delta;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, ShapeCount<Tile>::kWc, Threads::kH * kAccessSize> ImmediateOffsetStrides;
-
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE Coord<4> operator()() const {
- int offset = ComputeThreadOffsetFromStrides<Threads, ThreadsStrides>::get();
- return make_Coord(0, 0, offset, 0);
- }
- };
-
- protected:
- /// The strides to compute the base position of the thread.
- typedef Shape<0, kScalarsPerSts_, ShapeCount<Tile>::kHwc / Threads::kW> ThreadsStrides;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_,
- typename OutputTile_,
- typename Warps_,
- typename ThreadsPerWarp_,
- typename InstructionShape_,
- int kStages_,
- int kScalarsPerLds_,
- int kSkew_ = 0>
-struct GemmSharedLoadTileATraits {
- static GemmOperand::Kind const kOperand = GemmOperand::kA;
- /// The scalar.
- typedef typename platform::remove_const<Scalar_>::type Scalar;
- /// The pointer.
- typedef Scalar_* Pointer;
- /// The tile without skew.
- typedef Shape<kStages_,
- OutputTile_::kD / InstructionShape_::kD,
- GetExtent<kOperand, OutputTile_>::kExtent * InstructionShape_::kD>
- TileWithoutSkew_;
- /// The tile with skew.
- typedef Shape<kStages_, TileWithoutSkew_::kH, TileWithoutSkew_::kW + kSkew_> TileWithSkew;
- /// The tile without skew after reshaping.
- typedef typename ReshapeTile<TileWithoutSkew_, kScalarsPerLds_>::Tile TileWithoutSkew;
- /// The tile.
- typedef typename ReshapeTile<TileWithSkew, kScalarsPerLds_>::Tile Tile;
- /// The number of warps.
- typedef Warps_ Warps;
- /// The threads in a warp.
- typedef ThreadsPerWarp_ ThreadsPerWarp;
- /// The number of scalars per LDG/STG.
- // static int const kScalarsPerLds = kScalarsPerLds_;
- static int const kAccessSize = kScalarsPerLds_;
- /// The skew.
- static int const kSkew = kSkew_;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
-
- /// The number of warps.
- static int const kWarps = GetExtent<kOperand, Warps>::kExtent;
- /// The number of threads in one dimension of the warp.
- static int const kThreadsPerWarp = GetExtent<kOperand, ThreadsPerWarp>::kExtent;
-
- /// The number of iterations needed to load/store the tile.
- typedef Shape<1, 1, TileWithoutSkew::kW / kWarps / kThreadsPerWarp /* / kScalarsPerLds*/>
- Iterations;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<TileWithSkew::kW * Warps::kD, 0, kWarps * kThreadsPerWarp * kAccessSize, 0>
- ImmediateOffsetStrides;
- typedef Shape<TileWithSkew::kW * Warps::kD, 0, kWarps * kThreadsPerWarp * kAccessSize, 0> Delta;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE Coord<4> operator()() const {
- // Extract the warp.
- int const warp = threadIdx.x / kWarpSize;
- // Extract the slice.
- int const slice = warp / (Warps::kH * Warps::kW);
- // Compute the row offset for each warp.
- int const warp_row = warp % Warps::kW;
- // Compute the row offset for each thread.
- int const lane_row = (threadIdx.x & 0x0e) / 2;
- // The offset.
- int const offset =
- slice * Tile::kW * Tile::kC + (warp_row * ThreadsPerWarp::kW + lane_row) * kAccessSize;
- // Embed the offset in a 4D coordinate vector.
- return make_Coord(0, 0, offset, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_,
- typename OutputTile_,
- typename Warps_,
- typename ThreadsPerWarp_,
- typename InstructionShape_,
- int kStages_,
- int kScalarsPerLds_,
- int kSkew_ = 0>
-struct GemmSharedLoadTileBTraits {
- static GemmOperand::Kind const kOperand = GemmOperand::kB;
- /// The scalar.
- typedef typename platform::remove_const<Scalar_>::type Scalar;
- /// The pointer.
- typedef Scalar_* Pointer;
- /// The tile without skew.
- typedef Shape<kStages_,
- OutputTile_::kD / InstructionShape_::kD,
- GetExtent<kOperand, OutputTile_>::kExtent * InstructionShape_::kD>
- TileWithoutSkew_;
- /// The tile with skew.
- typedef Shape<kStages_, TileWithoutSkew_::kH, TileWithoutSkew_::kW + kSkew_> TileWithSkew;
- /// The tile without skew after reshaping.
- typedef typename ReshapeTile<TileWithoutSkew_, kScalarsPerLds_>::Tile TileWithoutSkew;
- /// The tile.
- typedef typename ReshapeTile<TileWithSkew, kScalarsPerLds_>::Tile Tile;
- /// The number of warps.
- typedef Warps_ Warps;
- /// The threads in a warp.
- typedef ThreadsPerWarp_ ThreadsPerWarp;
- /// The number of scalars per LDG/STG.
- static int const kAccessSize = kScalarsPerLds_;
- /// The skew.
- static int const kSkew = kSkew_;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
-
- /// The number of warps.
- static int const kWarps = GetExtent<kOperand, Warps>::kExtent;
- /// The number of threads in one dimension of the warp.
- static int const kThreadsPerWarp = GetExtent<kOperand, ThreadsPerWarp>::kExtent;
-
- /// The number of iterations needed to load/store the tile.
- typedef Shape<1, 1, TileWithoutSkew::kW / kWarps / kThreadsPerWarp /* / kAccessSize*/> Iterations;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<TileWithSkew::kW * Warps::kD, 0, kWarps * kThreadsPerWarp * kAccessSize, 0>
- ImmediateOffsetStrides;
- typedef Shape<TileWithSkew::kW * Warps::kD, 0, kWarps * kThreadsPerWarp * kAccessSize, 0> Delta;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE Coord<4> operator()() const {
- // Extract the warp.
- int const warp = threadIdx.x / kWarpSize;
- // Extract the slice.
- int const slice = warp / (Warps::kH * Warps::kW);
- // The warp in the slice.
- int const warp_in_slice = warp % (Warps::kH * Warps::kW);
- // Compute the row offset for each warp.
- int const warp_col = warp_in_slice / Warps::kW;
- // Compute the row offset for each thread.
- int const lane_col = (threadIdx.x & 0x10) / 8 + (threadIdx.x & 0x01);
- // The offset.
- int const offset =
- slice * Tile::kW * Tile::kC + (warp_col * ThreadsPerWarp::kH + lane_col) * kAccessSize;
- // Embed the offset in a 4D coordinate.
- return make_Coord(0, 0, offset, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_,
- typename OutputTile_,
- typename Warps_,
- typename ThreadsPerWarp_,
- int kScalarsPerSts_,
- int kSkew_ = 0>
-struct GemmSharedStoreTileDTraits {
- /// The scalar.
- typedef typename platform::remove_const<Scalar_>::type Scalar;
- /// The pointer.
- typedef Scalar_* Pointer;
- /// The dimension of the output tile.
- typedef OutputTile_ OutputTile;
- /// The warps in the tile.
- typedef Warps_ Warps;
- /// The threads in the warps.
- typedef ThreadsPerWarp_ ThreadsPerWarp;
- /// The number of scalars per LDG/STG.
- static int const kAccessSize = kScalarsPerSts_;
- /// The skew.
- static int const kSkew = kSkew_;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
-
- /// The number of scalars per thread.
- static int const kScalarsPerThread = OutputTile_::kW / Warps::kW / ThreadsPerWarp::kW;
- /// The number of threads.
- static int const kThreads = ShapeCount<Warps>::kCount * kWarpSize;
- /// The number of scalars per row. We build a tile with 2 rows (to avoid bank conflicts).
- static int const kScalarsPerRow = kThreads / 2 * kScalarsPerThread + kSkew;
-
- /// The tile.
- typedef Shape<1, 2, kScalarsPerRow / kAccessSize, kAccessSize> Tile;
- /// The number of iterations needed to store the tile.
- typedef Shape<1, 1, kScalarsPerThread / kAccessSize> Iterations;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, 0, Warps::kW * ThreadsPerWarp::kW * kAccessSize> Delta;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, 0, Warps::kW * ThreadsPerWarp::kW * kAccessSize> ImmediateOffsetStrides;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE Coord<4> operator()() const {
- // The warp.
- int const warp = threadIdx.x / kWarpSize;
-
- // The position of the warp in the 2D tile.
- int const warp_row = warp % Warps::kW;
- int const warp_col = warp / Warps::kW;
-
- // We assume that the elements are distributed in a warps as 4 columns of 8 elements. The
- // columns are stored in threads col0=[0, 2, 4, 6, 8, 10, 12, 14], col1=[1, 3, 5, 7, .., 15],
- // col2=[16, 18, 20, ..., 30] and col3=[17, 19, ..., 31].
- int hi_halfwarp_offset = ((threadIdx.x >> 4) & 0x1) * OutputTile::kW;
- int lo_halfwarp_offset = ((threadIdx.x >> 1) & 0x7) + ThreadsPerWarp::kW * warp_row;
-
- // Odd threads go to the second half of shared memory.
- int const row = threadIdx.x & 0x01;
- int col = warp_col * (ThreadsPerWarp::kH / 2) * OutputTile::kW +
- lo_halfwarp_offset * kAccessSize + hi_halfwarp_offset;
- // Embed the offset in a 4D coords.
- return make_Coord(0, 0, row * kScalarsPerRow + col, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_,
- typename OutputTile_,
- typename Warps_,
- typename ThreadsPerWarp_,
- int kTileH_,
- int kScalarsPerLds_,
- int kSkew_ = 0>
-struct GemmSharedLoadTileDTraits {
- /// The scalar.
- typedef typename platform::remove_const<Scalar_>::type Scalar;
- /// The pointer.
- typedef Scalar_* Pointer;
- /// The dimension of the output tile.
- typedef OutputTile_ OutputTile;
- /// The warps in the tile.
- typedef Warps_ Warps;
- /// The threads in the warps.
- typedef ThreadsPerWarp_ ThreadsPerWarp;
- /// The number of scalars per LDG/STG.
- static int const kAccessSize = kScalarsPerLds_;
- /// The skew.
- static int const kSkew = kSkew_;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
-
- /// The number of scalars per thread.
- static int const kScalarsPerThread = OutputTile_::kW / Warps::kW / ThreadsPerWarp::kW;
- /// The number of threads.
- static int const kThreads = ShapeCount<Warps>::kCount * kWarpSize;
- /// The number of scalars per row. We build a tile with 2 rows (to avoid bank conflicts).
- static int const kScalarsPerRow = kThreads / 2 * kScalarsPerThread + kSkew;
-
- /// The tile. We have 2 rows of scalars. We use those two rows to make sure we do not have bank
- /// conflicts in the epilogue.
- typedef Shape<1, 2, kScalarsPerRow / kAccessSize, kAccessSize> Tile;
-
- // Compute the number of iterations per warp in the Tile::kH dimension.
- static int const kIterationsInHPerWarp = kTileH_ / ShapeCount<Warps>::kCount;
-
- // As explained above, the shared memory tile is composed of 2 rows and each rows is made of
- // kScalarsPerRow. A warp is expected to read from the 1st row, then move to the 2nd row and go
- // back to the 1st row. To model that scheme we define the Iterations shape as Shape<X, 2, ...>.
- // However, in some cases, we have only 1 iteration per warp. In that case, we must define the
- // shape as Shape<1, 1, ...>. The following code does that except that we hijack the kH dimension
- // to keep the number of elements to reduce for split-K.
- static int const kIterationsH = kIterationsInHPerWarp == 1 ? 1 : 2;
- // As soon as we know kIterationsH, it is trivial to compute kIterationsD:
- static int const kIterationsD = kIterationsInHPerWarp / kIterationsH;
-
- // If we have split-K enabled, we have to jump over the elements from the "odd/even" column of
- // threads to grab the other elements.
- static int const kSplitK = OutputTile::kW * ThreadsPerWarp::kH / 2 * Warps::kH;
-
- /// The number of iterations needed to store the tile.
- typedef Shape<kIterationsD, kIterationsH, OutputTile::kW / kWarpSize / kAccessSize, Warps::kD>
- Iterations;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<OutputTile::kW, kScalarsPerRow, kWarpSize * kAccessSize, kSplitK>
- ImmediateOffsetStrides;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<OutputTile::kW, kScalarsPerRow, kWarpSize * kAccessSize, kSplitK> Delta;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE Coord<4> operator()() const {
- // Each warp works on a different column.
- int const h = threadIdx.x / kWarpSize;
- // Compute the row.
- int const w = (threadIdx.x & (kWarpSize - 1)) * kAccessSize;
- int offset = 0;
- if (Iterations::kH == 1) {
- int const row = h & 0x1;
- int const col = h / 2;
- offset = row * ShapeCount<Tile>::kWc + col * OutputTile::kW * Iterations::kD + w;
- } else {
- offset = h * OutputTile::kW * Iterations::kD + w;
- }
- return make_Coord(0, 0, offset, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/gemm_traits.h b/cutlass-example/cutlass/gemm/gemm_traits.h
deleted file mode 100644
index cb57c4d..0000000
--- a/cutlass-example/cutlass/gemm/gemm_traits.h
+++ /dev/null
@@ -1,818 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines structural properties of complete GEMM computation.
-*/
-#pragma once
-
-#include <cutlass/convert.h>
-#include <cutlass/gemm/clear_accumulators.h>
-#include <cutlass/gemm/gemm_global_stream.h>
-#include <cutlass/gemm/gemm_operand.h>
-#include <cutlass/gemm/gemm_shared_stream.h>
-#include <cutlass/gemm/identity_block_swizzle.h>
-#include <cutlass/matrix_traits.h>
-#include <cutlass/reshape_tile.h>
-#include <cutlass/tile_iterator.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The scalar type for A.
- typename ScalarA_,
- /// The scalar type for B.
- typename ScalarB_,
- /// The scalar type for C.
- typename ScalarC_,
- /// The scalar type for D.
- typename ScalarD_,
- /// The output tile size for the GEMM KxNxM.
- typename OutputTile_,
- /// The functor to do the math.
- typename MultiplyAdd_,
- /// The number of scalars per LDG for A.
- int kScalarsPerLdgA_,
- /// The number of scalars per STS for A.
- int kScalarsPerStsA_,
- /// The number of scalars per LDG for A.
- int kScalarsPerLdsA_,
- /// The number of scalars per LDG for B.
- int kScalarsPerLdgB_,
- /// The number of scalars per STS for B.
- int kScalarsPerStsB_,
- /// The number of scalars per LDS for B.
- int kScalarsPerLdsB_,
- /// The number of scalars per LDG for C and STG for D.
- int kScalarsPerLdgCAndStgD_,
- /// The number of scalars per STS for D.
- int kScalarsPerStsD_,
- /// The number of scalars per LDS for D.
- int kScalarsPerLdsD_,
- /// The number of stages in shared memory to do single/double/triple-buffering.
- int kStages_,
- /// Do we do the residue in the prologue?
- bool kResidueInPrologue_ = false>
-
-struct GemmConfig {
- //
- /// The scalar for A.
- typedef ScalarA_ ScalarA;
- /// The scalar for B.
- typedef ScalarB_ ScalarB;
- /// The scalar for C.
- typedef ScalarC_ ScalarC;
- /// The scalar for D.
- typedef ScalarD_ ScalarD;
-
- /// The tile.
- typedef OutputTile_ OutputTile;
- /// The functor to do D = A*B + C.
- typedef MultiplyAdd_ MultiplyAdd;
- /// The shape of the instruction.
- typedef typename MultiplyAdd::InstructionShape InstructionShape;
- /// The number of accumulators per warp.
- typedef typename MultiplyAdd::AccumulatorsPerWarp AccumulatorsPerWarp;
- /// The accumulators.
- typedef typename MultiplyAdd::Accumulators Accumulators;
-
- /// The number of warps.
- typedef typename ShapeDiv<OutputTile, AccumulatorsPerWarp>::Shape Warps;
- /// The default warp size (32 threads per warp).
- static int const kWarpSize = cutlass::kWarpSize;
- /// The numnber of threads.
- static int const kThreads = ShapeCount<Warps>::kCount * kWarpSize;
-
- /// The number of scalars per LDG/STS/LDS for A.
- static int const kScalarsPerLdgA = kScalarsPerLdgA_;
- static int const kScalarsPerStsA = kScalarsPerStsA_;
- static int const kScalarsPerLdsA = kScalarsPerLdsA_;
-
- /// The number of scalars per LDG/STS/LDS for B.
- static int const kScalarsPerLdgB = kScalarsPerLdgB_;
- static int const kScalarsPerStsB = kScalarsPerStsB_;
- static int const kScalarsPerLdsB = kScalarsPerLdsB_;
-
- /// The number of scalars per LDG for C.
- static int const kScalarsPerLdgC = kScalarsPerLdgCAndStgD_;
-
- /// The number of scalars per STS/LDS/STG for D.
- static int const kScalarsPerStgD = kScalarsPerLdgCAndStgD_;
- static int const kScalarsPerStsD = kScalarsPerStsD_;
- static int const kScalarsPerLdsD = kScalarsPerLdsD_;
-
- /// The number of accumulators that are going to be fed from one LDS A/B.
- static int const kAccumulatorsPerLdsA = kScalarsPerLdsA / InstructionShape::kD;
- static int const kAccumulatorsPerLdsB = kScalarsPerLdsB / InstructionShape::kD;
-
- /// The number of stages in shared memory to implement double, triple, more-buffering.
- static int const kStages = kStages_;
-
- /// Do we do the residue in the prologue?
- static bool const kResidueInPrologue = kResidueInPrologue_;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind, typename GemmConfig_>
-struct GemmTileTraitsHelperA {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct GemmTileTraitsHelperA<MatrixLayout::kColumnMajor, GemmConfig_> {
- /// The layout.
- static MatrixLayout::Kind const kLayout = MatrixLayout::kColumnMajor;
-
- /// The input scalar.
- typedef typename GemmConfig_::ScalarA Scalar;
- /// The scalar stored in shared memory.
- typedef typename GemmConfig_::MultiplyAdd::ScalarA MultiplyAddScalar;
-
- /// The traits class to build the iterator to load data from global memory for A^N.
- typedef GemmGlobalTileTraits<
- // That's A.
- GemmOperand::kA,
- // A is column-major.
- MatrixLayout::kColumnMajor,
- // The pointer is float const.
- Scalar const,
- // The tile has size KxM in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kW>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgA>
- GlobalTileTraits;
-
- /// The traits class to build the iterator to store data to shared memory for A^N.
- typedef GemmSharedStoreTileAbTraits<
- // The pointer is float.
- MultiplyAddScalar,
- // The tile has size KxM in GEMM's terminology.
- Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kD / GemmConfig_::InstructionShape::kD,
- GemmConfig_::OutputTile::kW * GemmConfig_::InstructionShape::kD>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- GemmConfig_::kScalarsPerStsA>
- SharedStoreTileTraits;
-
- /// The traits class to build the iterator to load from shared memory for A^N.
- typedef GemmSharedLoadTileATraits<
- // The pointer is float const.
- MultiplyAddScalar const,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The shape of the FMA instruction.
- typename GemmConfig_::InstructionShape,
- // The number of stages.
- GemmConfig_::kStages,
- // The number of scalars per LDS.
- GemmConfig_::kScalarsPerLdsA,
- // The skew.
- 0>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct GemmTileTraitsHelperA<MatrixLayout::kRowMajor, GemmConfig_> {
- /// The layout.
- static MatrixLayout::Kind const kLayout = MatrixLayout::kRowMajor;
-
- /// The input scalar.
- typedef typename GemmConfig_::ScalarA Scalar;
- /// The scalar stored in shared memory.
- typedef typename GemmConfig_::MultiplyAdd::ScalarA MultiplyAddScalar;
-
- /// The traits class to build the iterator to load data from global memory for A^T.
- typedef GemmGlobalTileTraits<
- // That's A.
- GemmOperand::kA,
- // A is row-major.
- MatrixLayout::kRowMajor,
- // The pointer is float const.
- Scalar const,
- // The tile has size MxK in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kW, GemmConfig_::OutputTile::kD>,
- // The threads are distributed as (threads / K) x K (the traits may reorganize).
- Shape<1, GemmConfig_::kThreads / GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kD>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgA>
- GlobalTileTraits;
-
- /// The number of scalars in 4B.
- static int const kScalarsIn4B = sizeof(MultiplyAddScalar) > 4 ? 1 : 4 / sizeof(MultiplyAddScalar);
- /// The skew for A.
- static int const kSkewA = 128 / sizeof(MultiplyAddScalar) / GemmConfig_::kScalarsPerStsA /
- GlobalTileTraits::Threads::kW * kScalarsIn4B;
-
- /// The traits class to build the iterator to store data to shared memory for A^T.
- typedef GemmSharedStoreWithSkewTileAbTraits <
- // The pointer is float.
- MultiplyAddScalar,
- // The tile has size KxM in GEMM's terminology.
- Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kD / GemmConfig_::InstructionShape::kD,
- GemmConfig_::OutputTile::kW * GemmConfig_::InstructionShape::kD>,
- // The threads are distributed as (threads / K) x K (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS.
- GemmConfig_::kScalarsPerStsA,
- // The skew to avoid bank conflicts added in the tile W dimension.
- kSkewA<GemmConfig_::kScalarsPerLdsA ? GemmConfig_::kScalarsPerLdsA : kSkewA>
- SharedStoreTileTraits;
-
- /// The traits class to build the iterator to load from shared memory for A^T.
- typedef GemmSharedLoadTileATraits<
- // The pointer is float const.
- MultiplyAddScalar const,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The shape of the FMA instruction.
- typename GemmConfig_::InstructionShape,
- // The number of stages.
- GemmConfig_::kStages,
- // The number of scalars per LDS.
- GemmConfig_::kScalarsPerLdsA,
- // The skew.
- SharedStoreTileTraits::kSkew>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind, typename GemmConfig_>
-struct GemmTileTraitsHelperB {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct GemmTileTraitsHelperB<MatrixLayout::kColumnMajor, GemmConfig_> {
- /// The layout.
- static MatrixLayout::Kind const kLayout = MatrixLayout::kColumnMajor;
-
- /// The input scalar.
- typedef typename GemmConfig_::ScalarB Scalar;
- /// The scalar stored in shared memory.
- typedef typename GemmConfig_::MultiplyAdd::ScalarB MultiplyAddScalar;
-
- /// The traits class to build the iterator to load data from global memory for B^N.
- typedef GemmGlobalTileTraits<
- // That's B.
- GemmOperand::kB,
- // B is column-major.
- MatrixLayout::kColumnMajor,
- // The pointer is float const.
- Scalar const,
- // The tile has size MxK in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kH, GemmConfig_::OutputTile::kD>,
- // The threads are distributed as (threads / K) x K (the traits may reorganize).
- Shape<1, GemmConfig_::kThreads / GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kD>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgB>
- GlobalTileTraits;
-
- /// The number of scalars in 4B.
- static int const kScalarsIn4B = sizeof(MultiplyAddScalar) > 4 ? 1 : 4 / sizeof(MultiplyAddScalar);
- /// The skew for B.
- static int const kSkewB = 128 / sizeof(MultiplyAddScalar) / GemmConfig_::kScalarsPerStsB /
- GlobalTileTraits::Threads::kW * kScalarsIn4B;
-
- /// The traits class to build the iterator to store data to shared memory for B^N.
- typedef GemmSharedStoreWithSkewTileAbTraits <
- // The pointer is float.
- MultiplyAddScalar,
- // The tile has size KxN in GEMM's terminology.
- Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kD / GemmConfig_::InstructionShape::kD,
- GemmConfig_::OutputTile::kH * GemmConfig_::InstructionShape::kD>,
- // The threads are distributed as (threads / K) x K (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS.
- GemmConfig_::kScalarsPerStsB,
- // The skew to avoid bank conflicts added in the tile W dimension.
- kSkewB<GemmConfig_::kScalarsPerLdsB ? GemmConfig_::kScalarsPerLdsB : kSkewB>
- SharedStoreTileTraits;
-
- /// The traits class to build the iterator to load from shared memory for B^N.
- typedef GemmSharedLoadTileBTraits<
- // The pointer is float const.
- MultiplyAddScalar const,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The shape of the FMA instruction.
- typename GemmConfig_::InstructionShape,
- // The number of stages.
- GemmConfig_::kStages,
- // The number of scalars per LDS.
- GemmConfig_::kScalarsPerLdsB,
- // The skew.
- SharedStoreTileTraits::kSkew>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct GemmTileTraitsHelperB<MatrixLayout::kRowMajor, GemmConfig_> {
- /// The layout.
- static MatrixLayout::Kind const kLayout = MatrixLayout::kRowMajor;
-
- /// The input scalar.
- typedef typename GemmConfig_::ScalarB Scalar;
- /// The scalar stored in shared memory.
- typedef typename GemmConfig_::MultiplyAdd::ScalarB MultiplyAddScalar;
-
- /// The traits class to build the iterator to load data from global memory for B^T.
- typedef GemmGlobalTileTraits<
- // That's B.
- GemmOperand::kB,
- // B is row-major.
- MatrixLayout::kRowMajor,
- // The pointer is float const.
- Scalar const,
- // The tile has size KxN in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kH>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgB>
- GlobalTileTraits;
-
- /// The traits class to build the iterator to store data to shared memory for B^T.
- typedef GemmSharedStoreTileAbTraits<
- // The pointer is float.
- MultiplyAddScalar,
- // The tile has size KxN in GEMM's terminology.
- Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kD / GemmConfig_::InstructionShape::kD,
- GemmConfig_::OutputTile::kH * GemmConfig_::InstructionShape::kD>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- GemmConfig_::kScalarsPerStsB>
- SharedStoreTileTraits;
-
- /// The traits class to build the iterator to load from shared memory for B^T.
- typedef GemmSharedLoadTileBTraits<
- // The pointer is float const.
- MultiplyAddScalar const,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The shape of the FMA instruction.
- typename GemmConfig_::InstructionShape,
- // The number of stages.
- GemmConfig_::kStages,
- // The number of scalars per LDS.
- GemmConfig_::kScalarsPerLdsB,
- // The skew.
- 0>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmTraits_, bool kResidueInPrologue_ = GemmTraits_::kResidueInPrologue>
-struct GemmResidue {
- /// Move to residue portion.
- template <bool kIsPrologue>
- static CUTLASS_DEVICE void move_to_residue(typename GemmTraits_::GlobalLoadStreamA& stream_a,
- typename GemmTraits_::GlobalLoadStreamB& stream_b,
- typename GemmTraits_::Index k) {
- // The new code path in CUTLASS 1.0.1: We treat the residue in the prologue so we can have
- // complete main loops after that. It helps simplify the logic in the main loop.
- if (kIsPrologue) {
- stream_a.move_to_residue(k);
- stream_b.move_to_residue(k);
- }
- }
-
- /// Rollback to beginning of first tile and initialize predicates.
- static CUTLASS_DEVICE void rollback(typename GemmTraits_::GlobalLoadStreamA& stream_a,
- typename GemmTraits_::GlobalLoadStreamB& stream_b) {
- stream_a.rollback();
- stream_b.rollback();
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmTraits_>
-struct GemmResidue<GemmTraits_, false> {
- /// Move to residue portion.
- template <bool kIsPrologue>
- static CUTLASS_DEVICE void move_to_residue(typename GemmTraits_::GlobalLoadStreamA& stream_a,
- typename GemmTraits_::GlobalLoadStreamB& stream_b,
- typename GemmTraits_::Index k) {
- // The index.
- typedef typename GemmTraits_::Index Index;
- // By how much we unroll the main loop.
- Index const kUnroll = static_cast<Index>(GemmTraits_::OutputTile::kD);
-
- // Call the residue code. That's the same path as CUTLASS 1.0.0.
- if (kIsPrologue && k < kUnroll) {
- stream_a.residue(k, true);
- stream_b.residue(k, true);
- } else if (k <= kUnroll) {
- stream_a.residue(k, false);
- stream_b.residue(k, false);
- }
- }
-
- /// Rollback to beginning of first tile and initialize predicates.
- static CUTLASS_DEVICE void rollback(typename GemmTraits_::GlobalLoadStreamA& stream_a,
- typename GemmTraits_::GlobalLoadStreamB& stream_b) {}
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The GEMM configuration.
- typename GemmConfig_,
- /// The stream to load A from global memory to shared memory.
- typename GlobalLoadStreamA_,
- /// The stream to load B from global memory to shared memory.
- typename GlobalLoadStreamB_,
- /// The stream to load A from shared memory.
- typename SharedLoadStreamA_,
- /// The stream to load B from shared memory.
- typename SharedLoadStreamB_,
- /// The epilogue.
- typename Epilogue_,
- /// The block swizzle to reorganize the grid.
- typename BlockSwizzle_ = IdentityBlockSwizzle,
- /// The index.
- typename Index_ = int,
- /// The tool used to clear accumulators.
- typename ClearAccumulators_ = ClearAccumulators<typename GemmConfig_::Accumulators::Scalar> >
-
-struct GemmTraits {
- /// This class.
- typedef GemmTraits<GemmConfig_,
- GlobalLoadStreamA_,
- GlobalLoadStreamB_,
- SharedLoadStreamA_,
- SharedLoadStreamB_,
- Epilogue_,
- BlockSwizzle_,
- Index_,
- ClearAccumulators_>
- This_;
-
- /// The configuration.
- typedef GemmConfig_ GemmConfig;
- /// The output tile.
- typedef typename GemmConfig::OutputTile OutputTile;
- /// Is the residue treated in the prologue?
- static bool const kResidueInPrologue = GemmConfig::kResidueInPrologue;
-
- /// The stream to load A from global memory to shared memory.
- typedef GlobalLoadStreamA_ GlobalLoadStreamA;
- /// The layout of A.
- static MatrixLayout::Kind const kLayoutA = GlobalLoadStreamA::kLayout;
- /// The scalar for A.
- typedef typename GlobalLoadStreamA_::Scalar ScalarA;
-
- /// The stream to load B from global memory to shared memory.
- typedef GlobalLoadStreamB_ GlobalLoadStreamB;
- /// The layout of B.
- static MatrixLayout::Kind const kLayoutB = GlobalLoadStreamB::kLayout;
- /// The scalar for B.
- typedef typename GlobalLoadStreamB_::Scalar ScalarB;
-
- /// The iterator for A to load from shared memory.
- typedef SharedLoadStreamA_ SharedLoadStreamA;
- /// The iterator for B to load from shared memory.
- typedef SharedLoadStreamB_ SharedLoadStreamB;
-
- /// The multiply-add functor.
- typedef typename GemmConfig::MultiplyAdd MultiplyAdd;
- /// The epilogue.
- typedef Epilogue_ Epilogue;
- /// The scalars in the epilogue.
- typedef typename Epilogue::ScalarC ScalarC;
- typedef typename Epilogue::ScalarD ScalarD;
-
- /// The block swizzle to reorganize the grid.
- typedef BlockSwizzle_ BlockSwizzle;
- /// The index.
- typedef Index_ Index;
- /// Clear the accumulators.
- typedef ClearAccumulators_ ClearAccumulators;
-
- /// The params.
- struct Params {
- /// The dimensions of the GEMM.
- Index m, n, k;
- /// The params for the A stream.
- typename GlobalLoadStreamA::Params global_stream_a;
- /// The params for the B stream.
- typename GlobalLoadStreamB::Params global_stream_b;
- /// The params for the A stream from shared memory.
- typename SharedLoadStreamA::Params shared_stream_a;
- /// The params for the B stream from shared memory.
- typename SharedLoadStreamB::Params shared_stream_b;
- /// The params for the epilogue.
- typename Epilogue::Params epilogue;
-
- /// Initialize the parameters.
- template <typename GemmDesc_>
- CUTLASS_HOST_DEVICE int initialize(GemmDesc_ const& desc) {
- // Set the problem size.
- this->m = desc.m;
- this->n = desc.n;
- this->k = desc.k;
-
- // Initialize the iterator for A.
- int error_code =
- global_stream_a.initialize(desc, reinterpret_cast<ScalarA const*>(desc.d_a), desc.lda);
-
- if (error_code) {
- return error_code;
- }
-
- // Initialize the iterator for B.
- error_code =
- global_stream_b.initialize(desc, reinterpret_cast<ScalarB const*>(desc.d_b), desc.ldb);
-
- if (error_code) {
- return error_code;
- }
-
- // The epilogue.
- return epilogue.initialize(desc);
- }
- };
-
- // The storage for A.
- template <typename GlobalLoadStream_, typename SharedLoadStream_>
- union StreamSharedStorage {
- // The storage needed by the global stream.
- typename GlobalLoadStream_::SharedStorage global;
- // The storage needed by the shared stream.
- typename SharedLoadStream_::SharedStorage shared;
- };
-
- // The storage for the main loop + prologue.
- struct MainLoopSharedStorage {
- // The storage to shuffle the A matrix in shared memory.
- StreamSharedStorage<GlobalLoadStreamA, SharedLoadStreamA> stream_a;
- // The storage to shuffle the B matrix in shared memory.
- StreamSharedStorage<GlobalLoadStreamB, SharedLoadStreamB> stream_b;
- // The storage to clear the accumulators if needed.
- typename ClearAccumulators::SharedStorage clear;
- };
-
- /// The storage in shared memory.
- union SharedStorage {
- // The storage for the main loop.
- MainLoopSharedStorage main_loop;
- // The storage for the epilogue.
- typename Epilogue::SharedStorage epilogue;
- };
-
- /// Assemble the global load streams for A/B.
- struct GlobalLoadStream {
- /// Ctor.
- CUTLASS_DEVICE GlobalLoadStream(Params const& params,
- SharedStorage& shared_storage,
- dim3 const& block)
- : stream_a(params.global_stream_a,
- shared_storage.main_loop.stream_a.global,
- cutlass::make_Coord(0, params.k, params.m),
- cutlass::make_Coord(0, 0, block.x)),
- stream_b(params.global_stream_b,
- shared_storage.main_loop.stream_b.global,
- cutlass::make_Coord(0, params.k, params.n),
- make_Coord(0, 0, block.y)) {}
-
- /// Trigger the copies from shared memory to registers.
- CUTLASS_DEVICE void copy() {
- stream_a.copy();
- stream_b.copy();
- }
-
- /// Commit the data.
- CUTLASS_DEVICE void commit() {
- stream_a.commit();
- stream_b.commit();
- }
-
- /// Move to residue portion.
- template <bool kIsPrologue>
- CUTLASS_DEVICE void move_to_residue(Index k) {
- GemmResidue<This_>::move_to_residue<kIsPrologue>(stream_a, stream_b, k);
- }
-
- /// Rollback to beginning of first tile and initialize predicates.
- CUTLASS_DEVICE void rollback() { GemmResidue<This_>::rollback(stream_a, stream_b); }
-
- /// The stream for A.
- GlobalLoadStreamA stream_a;
- /// The stream for B.
- GlobalLoadStreamB stream_b;
- };
-
- /// Assemble the shared load stream for A/B.
- struct SharedLoadStream {
- /// Ctor.
- CUTLASS_DEVICE SharedLoadStream(Params const& params, SharedStorage& shared_storage) {
- stream_a.initialize(params.shared_stream_a, shared_storage.main_loop.stream_a.shared);
- stream_b.initialize(params.shared_stream_b, shared_storage.main_loop.stream_b.shared);
- }
-
- /// Trigger the copies from shared memory to registers.
- CUTLASS_DEVICE void copy(int step) {
- stream_a.copy(step, fetched_a[step % 2]);
- stream_b.copy(step, fetched_b[step % 2]);
- }
-
- /// Commit the data.
- CUTLASS_DEVICE void commit(int step) {
- stream_a.commit(fetched_a[step % 2], transformed_a[step % 2]);
- stream_b.commit(fetched_b[step % 2], transformed_b[step % 2]);
- }
-
- /// The fragment A.
- CUTLASS_DEVICE typename SharedLoadStreamA::Fragment const& fragment_a(int step) const {
- return transformed_a[step % 2];
- }
-
- /// The fragment B.
- CUTLASS_DEVICE typename SharedLoadStreamB::Fragment const& fragment_b(int step) const {
- return transformed_b[step % 2];
- }
-
- /// Increment the stage.
- CUTLASS_DEVICE void inc_stage() {
- stream_a.inc_stage();
- stream_b.inc_stage();
- }
-
- /// The stream for A.
- SharedLoadStreamA stream_a;
- /// The fragments to fetch A.
- typename SharedLoadStreamA::FetchedFragment fetched_a[2];
- /// The fragments to transform A.
- typename SharedLoadStreamA::TransformedFragment transformed_a[2];
- /// The stream for B.
- SharedLoadStreamB stream_b;
- /// The fragments to fetch B.
- typename SharedLoadStreamB::FetchedFragment fetched_b[2];
- /// The fragments to transform B.
- typename SharedLoadStreamB::TransformedFragment transformed_b[2];
- };
-
- /// The memory fence for shared loads.
- static CUTLASS_DEVICE void shared_load_fence(bool in_loop) {
- if (SharedLoadStreamA::Iterator::kRequiresLoadFence ||
- SharedLoadStreamB::Iterator::kRequiresLoadFence) {
- __syncthreads();
- }
- }
-
- /// The memory fence for shared stores.
- static CUTLASS_DEVICE void shared_store_fence(bool in_loop) { __syncthreads(); }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmTileTraitsHelperA_, typename GemmTileTraitsHelperB_, typename Index_>
-struct SimplifiedGemmTraitsHelper {
- /// The global iterator to load A from global memory.
- typedef GemmGlobalIteratorAb<typename GemmTileTraitsHelperA_::GlobalTileTraits, Index_>
- GlobalLoadIteratorA;
- /// The data converter for A before storing to shared memory.
- typedef Copy<typename GlobalLoadIteratorA::Fragment> GlobalTransformerA;
- /// The iterator to store A to shared memory.
- typedef TileStoreIterator<typename GemmTileTraitsHelperA_::SharedStoreTileTraits,
- typename GemmTileTraitsHelperA_::SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorA;
- /// The stream to load A from global memory to shared memory.
- typedef GlobalLoadStream<GlobalLoadIteratorA, SharedStoreIteratorA, GlobalTransformerA>
- GlobalLoadStreamA;
-
- /// The global iterator to load B from global memory.
- typedef GemmGlobalIteratorAb<typename GemmTileTraitsHelperB_::GlobalTileTraits, Index_>
- GlobalLoadIteratorB;
- /// The data converter for B before storing to shared memory.
- typedef Copy<typename GlobalLoadIteratorB::Fragment> GlobalTransformerB;
- /// The iterator to store B to shared memory.
- typedef TileStoreIterator<typename GemmTileTraitsHelperB_::SharedStoreTileTraits,
- typename GemmTileTraitsHelperB_::SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorB;
- /// The stream to load B from global memory to shared memory.
- typedef GlobalLoadStream<GlobalLoadIteratorB, SharedStoreIteratorB, GlobalTransformerB>
- GlobalLoadStreamB;
-
- /// The iterator to load A from shared memory.
- typedef TileLoadIterator<typename GemmTileTraitsHelperA_::SharedLoadTileTraits,
- typename GemmTileTraitsHelperA_::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorA;
- /// The stream to load A from shared memory.
- typedef SharedLoadStream<SharedLoadIteratorA> SharedLoadStreamA;
- /// The iterator to load B from shared memory.
- typedef TileLoadIterator<typename GemmTileTraitsHelperB_::SharedLoadTileTraits,
- typename GemmTileTraitsHelperB_::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorB;
- /// The stream to load B from shared memory.
- typedef SharedLoadStream<SharedLoadIteratorB> SharedLoadStreamB;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The config for the GEMM.
- typename GemmConfig_,
- /// The epilogue.
- typename Epilogue_,
- /// The index.
- typename Index_ = int,
- // The configuration for the A matrix.
- typename GemmTileTraitsHelperA_ = GemmTileTraitsHelperA<kLayoutA_, GemmConfig_>,
- // The configuration for the B matrix.
- typename GemmTileTraitsHelperB_ = GemmTileTraitsHelperB<kLayoutB_, GemmConfig_>,
- // The helper class to create the streams and iterators.
- typename Helper_ =
- SimplifiedGemmTraitsHelper<GemmTileTraitsHelperA_, GemmTileTraitsHelperB_, Index_> >
-struct SimplifiedGemmTraits : public GemmTraits<
- // The config.
- GemmConfig_,
- // The stream to load A from global memory to shared memory.
- typename Helper_::GlobalLoadStreamA,
- // The stream to load B from global memory to shared memory.
- typename Helper_::GlobalLoadStreamB,
- // The stream to load A from shared memory.
- typename Helper_::SharedLoadStreamA,
- // The stream to load B from shared memory.
- typename Helper_::SharedLoadStreamB,
- // The epilogue.
- Epilogue_,
- // The block swizzle to reorganize the grid.
- IdentityBlockSwizzle,
- // The index.
- Index_,
- // The tool used to clear accumulators.
- ClearAccumulators<typename GemmConfig_::Accumulators::Element> > {
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/hgemm_global_tile.h b/cutlass-example/cutlass/gemm/hgemm_global_tile.h
deleted file mode 100644
index f14dbb3..0000000
--- a/cutlass-example/cutlass/gemm/hgemm_global_tile.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Tile traits used to construct global tile iterator for HGEMM. This is intended to
- partition the thread block-level tile into 2D subtiles loaded by the threads and facilitate
- memory accesses larger than 16 bits.
-*/
-#pragma once
-
-#include <cutlass/coord.h>
-#include <cutlass/gemm/gemm_global_tile.h>
-#include <cutlass/matrix_traits.h>
-#include <cutlass/reshape_tile.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <GemmOperand::Kind kOperand_,
- MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename Tile_,
- typename Threads_,
- int kAccessSize_>
-struct HgemmCrosswiseGlobalTileTraits : public GemmGlobalTileTraits<
- // Which GEMM operand?
- kOperand_,
- // The layout.
- kLayout_,
- // The scalar.
- Scalar_,
- // The tile.
- Tile_,
- // The threads.
- Threads_,
- // The number of scalars per LDG/STG.
- kAccessSize_> {
- /// The base class.
- typedef GemmGlobalTileTraits<kOperand_, kLayout_, Scalar_, Tile_, Threads_, kAccessSize_> Base;
- /// The threads.
- typedef typename Base::Threads Threads;
- /// The threads strides.
- typedef Shape<1, 2, Base::Tile::kC> ThreadsDelta;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<Base::Threads::kH * 2, 1, Base::Threads::kW, Base::kAccessSize> Delta;
- /// The number of iterations needed to load/store the tile.
- typedef Shape<Base::Tile::kH / Base::Threads::kH / 2,
- 2,
- Base::Tile::kW / Base::Threads::kW,
- Base::Tile::kC / Base::kAccessSize>
- Iterations;
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- int thread_offset_h = threadIdx.x / Threads::kW * ThreadsDelta::kH;
- int thread_offset_w = threadIdx.x % Threads::kW * ThreadsDelta::kW;
-
- return make_Coord(0, thread_offset_h, thread_offset_w, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/hgemm_multiply_add.h b/cutlass-example/cutlass/gemm/hgemm_multiply_add.h
deleted file mode 100644
index ebbdd06..0000000
--- a/cutlass-example/cutlass/gemm/hgemm_multiply_add.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Specialization implementing multiply-add operation on half-precision floating point
- fragments.
-*/
-#pragma once
-
-#include <cutlass/fragment.h>
-
-#include <cutlass/gemm/thread_multiply_add.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Template performing matrix multiply-add operation within a thread
-template <typename AccumulatorsPerThread_, typename ThreadsPerWarp_>
-struct ThreadMultiplyAdd<AccumulatorsPerThread_, ThreadsPerWarp_, half, half, half> {
- /// The shape of the instruction.
- typedef Shape<1, 1, 2, 1> InstructionShape;
- /// The number of accumulators per thread.
- typedef AccumulatorsPerThread_ AccumulatorsPerThread;
- /// The number of threads per warp.
- typedef ThreadsPerWarp_ ThreadsPerWarp;
- /// The number of accumulators per warp.
- typedef typename ShapeMul<AccumulatorsPerThread, ThreadsPerWarp>::Shape AccumulatorsPerWarp;
- /// The type for A.
- typedef half ScalarA;
- /// The fragment for A.
- typedef Fragment<ScalarA, AccumulatorsPerThread::kW> FragmentA;
- /// The type for B.
- typedef half ScalarB;
- /// The fragment for B.
- typedef Fragment<ScalarB, AccumulatorsPerThread::kH> FragmentB;
- /// The type for C and D.
- typedef half ScalarC;
- /// The accumulators.
- typedef Fragment<half, AccumulatorsPerThread::kH * AccumulatorsPerThread::kW> Accumulators;
-
- /// Make sure there's an even number of elements in both dimensions.
- static_assert(AccumulatorsPerThread::kH % 2 == 0, "Invalid size");
- static_assert(AccumulatorsPerThread::kW % 2 == 0, "Invalid size");
-
- /// Ctor.
- CUTLASS_DEVICE ThreadMultiplyAdd() {}
-
- /// Multiply : d = a*b + c.
- CUTLASS_DEVICE void multiply_add(FragmentA const& a,
- FragmentB const& b,
- Accumulators const& c,
- Accumulators& d) {
-#if defined(__CUDACC__) && __CUDA_ARCH__ >= 530
- // The inputs.
- __half2 const* a_half2 = reinterpret_cast<__half2 const*>(&a[0]);
- __half2 const* b_half2 = reinterpret_cast<__half2 const*>(&b[0]);
- __half2 const* c_half2 = reinterpret_cast<__half2 const*>(&c[0]);
-
- // The output.
- __half2* d_half2 = reinterpret_cast<__half2*>(&d[0]);
-
- for (int j = 0; j < AccumulatorsPerThread::kH / 2; ++j) {
- for (int i = 0; i < AccumulatorsPerThread::kW / 2; ++i) {
- // The offsets in the output fragment.
- int const k0 = (2 * j + 0) * (AccumulatorsPerThread::kW / 2) + i;
- int const k1 = (2 * j + 1) * (AccumulatorsPerThread::kW / 2) + i;
-
- // Compute the product a[i] * b[j].H0_H0.
- d_half2[k0] = __hfma2(a_half2[i], __low2half2(b_half2[j]), c_half2[k0]);
- // Compute the product a[i] * b[j].H1_H1.
- d_half2[k1] = __hfma2(a_half2[i], __high2half2(b_half2[j]), c_half2[k1]);
- }
- }
-#endif
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/hgemm_swizzle.h b/cutlass-example/cutlass/gemm/hgemm_swizzle.h
deleted file mode 100644
index ebec0d4..0000000
--- a/cutlass-example/cutlass/gemm/hgemm_swizzle.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Transposes a tile of 16b elements. Used by HGEMM to construct a K-strided layout in
- shared memory for multiplicands.
-*/
-#pragma once
-
-#include <cuda_fp16.h>
-#include <cutlass/fragment.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GlobalIterator_>
-struct HgemmSwizzle {
- /// The global iterator.
- typedef GlobalIterator_ GlobalIterator;
- /// The source fragment.
- typedef typename GlobalIterator::Fragment Fragment;
- /// The shape of the source fragment.
- typedef typename GlobalIterator::FragmentShape FragmentShape;
-
- /// The input fragment.
- typedef Fragment InputFragment;
- /// The output fragment.
- typedef Fragment OutputFragment;
-
- /// The src/dst must be half fragments.
- static_assert((platform::is_same<typename Fragment::Element, half>::value), "Works on half");
-
- /// The number of elements must be a multiple of 2.
- static_assert(FragmentShape::kH == 2 && ShapeCount<FragmentShape>::kWc == 2, "Not multiple of 2");
-
- /// Ctor.
- CUTLASS_DEVICE HgemmSwizzle() {}
-
- /// Transform a fragment.
- CUTLASS_DEVICE void transform(Fragment const& src, Fragment& dst) {
- // Expose src/dst as int arrays.
- int const* src_int = reinterpret_cast<int const*>(&src[0]);
- int* dst_int = reinterpret_cast<int*>(&dst[0]);
-
- // Transpose the data.
- for (int d = 0; d < FragmentShape::kD; ++d) {
- // The indices to read two consecutive "rows".
- int const i0 = 2 * d + 0;
- int const i1 = 2 * d + 1;
-
- int a0 = src_int[i0];
- int a1 = src_int[i1];
-
- int b0, b1;
- asm volatile("prmt.b32 %0, %1, %2, 0x5410;" : "=r"(b0) : "r"(a0), "r"(a1));
- asm volatile("prmt.b32 %0, %1, %2, 0x7632;" : "=r"(b1) : "r"(a0), "r"(a1));
-
- // The indices to store with "strides".
- int const j0 = 0 * (ShapeCount<FragmentShape>::kDhw / 2) + d;
- int const j1 = 1 * (ShapeCount<FragmentShape>::kDhw / 2) + d;
-
- dst_int[j0] = b0;
- dst_int[j1] = b1;
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/hgemm_traits.h b/cutlass-example/cutlass/gemm/hgemm_traits.h
deleted file mode 100644
index b08645b..0000000
--- a/cutlass-example/cutlass/gemm/hgemm_traits.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defies structural properties of half-precision GEMM computation.
-*/
-#pragma once
-
-#include <cutlass/convert.h>
-#include <cutlass/reshape_tile.h>
-
-#include <cutlass/gemm/gemm.h>
-#include <cutlass/gemm/gemm_epilogue.h>
-#include <cutlass/gemm/gemm_epilogue_traits.h>
-#include <cutlass/gemm/gemm_global_tile.h>
-#include <cutlass/gemm/gemm_shared_tile.h>
-#include <cutlass/gemm/gemm_traits.h>
-#include <cutlass/gemm/hgemm_global_tile.h>
-#include <cutlass/gemm/hgemm_multiply_add.h>
-#include <cutlass/gemm/hgemm_swizzle.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The tile size for the GEMM KxNxM.
- typename OutputTile_,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_,
- /// The number of scalars per LDG for A.
- int kScalarsPerLdgA_ = 2,
- /// The number of scalars per LDG for B.
- int kScalarsPerLdgB_ = 2>
-struct HgemmConfig
- : public GemmConfig<
- /// The scalar type for A.
- half,
- /// The scalar type for B.
- half,
- /// The scalar type for C.
- half,
- /// The scalar type for D.
- half,
- /// The tile size for the GEMM KxNxM.
- OutputTile_,
- /// The functor to do the math in the main loop.
- ThreadMultiplyAdd<AccumulatorsPerThread_, Shape<1, 4, 8>, half, half, half>,
- /// The number of scalars per LDG for A.
- kScalarsPerLdgA_,
- /// The number of scalars per STS for A.
- kScalarsPerLdgA_,
- /// The number of scalars per LDS for A.
- 8,
- /// The number of scalars per LDG for B.
- kScalarsPerLdgB_,
- /// The number of scalars per STS for B.
- kScalarsPerLdgB_,
- /// The number of scalars per LDS for B.
- 8,
- /// The number of scalars per LDG for C and STG for D.
- 2,
- /// The number of scalars per STS for D.
- 8,
- /// The number of scalars per LDS for D.
- 2,
- /// The number of stages in shared memory.
- 2> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename Iterator_>
-struct HgemmTransformerA {};
-
-template <typename Iterator_>
-struct HgemmTransformerA<MatrixLayout::kColumnMajor, Iterator_> {
- typedef Convert<typename Iterator_::Fragment, typename Iterator_::Fragment> Transformer;
-};
-
-template <typename Iterator_>
-struct HgemmTransformerA<MatrixLayout::kRowMajor, Iterator_> {
- typedef HgemmSwizzle<Iterator_> Transformer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename Iterator_>
-struct HgemmTransformerB {};
-
-template <typename Iterator_>
-struct HgemmTransformerB<MatrixLayout::kRowMajor, Iterator_> {
- typedef Convert<typename Iterator_::Fragment, typename Iterator_::Fragment> Transformer;
-};
-
-template <typename Iterator_>
-struct HgemmTransformerB<MatrixLayout::kColumnMajor, Iterator_> {
- typedef HgemmSwizzle<Iterator_> Transformer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename GemmConfig_>
-struct HgemmTileTraitsHelperA : public GemmTileTraitsHelperA<kLayout_, GemmConfig_> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct HgemmTileTraitsHelperA<MatrixLayout::kRowMajor, GemmConfig_>
- : public GemmTileTraitsHelperA<MatrixLayout::kRowMajor, GemmConfig_> {
- /// The base config.
- typedef GemmTileTraitsHelperA<MatrixLayout::kRowMajor, GemmConfig_> Base;
-
- /// The traits class to build the iterator to load data from global memory for A^T.
- typedef HgemmCrosswiseGlobalTileTraits<
- GemmOperand::kA,
- // The layout.
- MatrixLayout::kRowMajor,
- // The pointer.
- half const,
- // The tile has size MxK in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kW, GemmConfig_::OutputTile::kD>,
- // The threads are distributed as (threads / K ) x K (the traits may reorganize).
- Shape<1, GemmConfig_::kThreads / GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kD>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc)
- GemmConfig_::kScalarsPerLdgA>
- GlobalTileTraits;
-
- /// The skew.
- static int const kSkewA = 128 / sizeof(half) / GlobalTileTraits::Threads::kW / 2;
-
- /// The traits class to build the iterator to store data to shared memory for A^T.
- typedef GemmSharedStoreWithSkewTileAbTraits <
- // The pointer.
- half,
- // The tile has size KxM in GEMM's terminology.
- Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kD / GemmConfig_::InstructionShape::kD,
- GemmConfig_::OutputTile::kW * GemmConfig_::InstructionShape::kD>,
- // The threads are distributed as warps x 32(the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- 2,
- // The skew to avoid bank conflicts added in the tile W dimension.
- kSkewA<GemmConfig_::kScalarsPerLdsA ? GemmConfig_::kScalarsPerLdsA : kSkewA>
- SharedStoreTileTraits;
-
- /// The traits class to build the iterator to load from shared memory for A^T.
- typedef GemmSharedLoadTileATraits<
- // The pointer.
- half const,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The shape of the FMA instruction.
- typename GemmConfig_::InstructionShape,
- // The number of stages.
- GemmConfig_::kStages,
- // The number of scalars per LDS.
- 8,
- // The skew.
- SharedStoreTileTraits::kSkew>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename GemmConfig_>
-struct HgemmTileTraitsHelperB : public GemmTileTraitsHelperB<kLayout_, GemmConfig_> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct HgemmTileTraitsHelperB<MatrixLayout::kColumnMajor, GemmConfig_>
- : public GemmTileTraitsHelperB<MatrixLayout::kColumnMajor, GemmConfig_> {
- /// The base config.
- typedef GemmTileTraitsHelperB<MatrixLayout::kColumnMajor, GemmConfig_> Base;
-
- /// The traits class to build the iterator to load data from global memory for B^N.
- typedef HgemmCrosswiseGlobalTileTraits<
- GemmOperand::kB,
- // The layout.
- MatrixLayout::kColumnMajor,
- // The pointer.
- half const,
- // The tile has size KxN in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kH, GemmConfig_::OutputTile::kD>,
- // The threads are distributed as (threads / K) x K (the traits may reorganize).
- Shape<1, GemmConfig_::kThreads / GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kD>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc)
- GemmConfig_::kScalarsPerLdgB>
- GlobalTileTraits;
-
- /// The skew for B.
- static int const kSkewB = 128 / sizeof(half) / GlobalTileTraits::Threads::kW / 2;
-
- /// The traits class to build the iterator to store data to shared memory for B^N.
- typedef GemmSharedStoreWithSkewTileAbTraits <
- // The pointer.
- half,
- // The tile has size KxN in GEMM's terminology.
- Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kD / GemmConfig_::InstructionShape::kD,
- GemmConfig_::OutputTile::kH * GemmConfig_::InstructionShape::kD>,
- // The threads are distributed as (threads / K) x K (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- 2,
- // The skew to avoid bank conflicts added in the tile W dimension.
- kSkewB<GemmConfig_::kScalarsPerLdsB ? GemmConfig_::kScalarsPerLdsB : kSkewB>
- SharedStoreTileTraits;
-
- /// The traits class to build the iterator to load from shared memory for B^N.
- typedef GemmSharedLoadTileBTraits<
- // The pointer.
- half const,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The shape of the FMA instruction.
- typename GemmConfig_::InstructionShape,
- // The number of stages.
- GemmConfig_::kStages,
- // The number of scalars per LDS.
- 8,
- // The skew.
- SharedStoreTileTraits::kSkew>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The output tile.
- typename OutputTile_,
- /// The functor to do the math in the epilogue.
- typename EpilogueFunctor_,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_ = Shape<8, 8, 16>,
- /// The number of halfs loaded in one LDG for A.
- int kScalarsPerLdgA_ = 2,
- /// The number of halfs loaded in one LDG for B.
- int kScalarsPerLdgB_ = 2,
- /// The index.
- typename Index_ = int>
-struct HgemmTraitsHelper {
- /// The HGEMM config.
- typedef HgemmConfig<OutputTile_, AccumulatorsPerThread_, kScalarsPerLdgA_, kScalarsPerLdgB_>
- GemmConfig;
- /// The GEMM config for A.
- typedef HgemmTileTraitsHelperA<kLayoutA_, GemmConfig> GemmTileTraitsHelperA;
- /// The GEMM config for B.
- typedef HgemmTileTraitsHelperB<kLayoutB_, GemmConfig> GemmTileTraitsHelperB;
-
- /// The iterator to load A from global memory.
- typedef GemmGlobalIteratorAb<typename GemmTileTraitsHelperA::GlobalTileTraits, Index_>
- GlobalLoadIteratorA;
- /// The default transformer for A.
- typedef typename HgemmTransformerA<GemmTileTraitsHelperA::kLayout,
- GlobalLoadIteratorA>::Transformer GlobalTransformerA;
- /// The iterator to store A to shared memory.
- typedef TileStoreIterator<typename GemmTileTraitsHelperA::SharedStoreTileTraits,
- typename GemmTileTraitsHelperA::SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorA;
- /// The stream to load A from global memory to shared memory.
- typedef GlobalLoadStream<GlobalLoadIteratorA, SharedStoreIteratorA, GlobalTransformerA>
- GlobalLoadStreamA;
-
- /// The iterator to load B from global memory.
- typedef GemmGlobalIteratorAb<typename GemmTileTraitsHelperB::GlobalTileTraits, Index_>
- GlobalLoadIteratorB;
- // The default transformer for B.
- typedef typename HgemmTransformerB<GemmTileTraitsHelperB::kLayout,
- GlobalLoadIteratorB>::Transformer GlobalTransformerB;
- /// The iterator to store B to shared memory.
- typedef TileStoreIterator<typename GemmTileTraitsHelperB::SharedStoreTileTraits,
- typename GemmTileTraitsHelperB::SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorB;
- /// The stream to load B from global memory to shared memory.
- typedef GlobalLoadStream<GlobalLoadIteratorB, SharedStoreIteratorB, GlobalTransformerB>
- GlobalLoadStreamB;
-
- /// The iterator to load A from shared memory
- typedef TileLoadIterator<typename GemmTileTraitsHelperA::SharedLoadTileTraits,
- typename GemmTileTraitsHelperA::SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorA;
- /// The stream to load A from shared memory.
- typedef SharedLoadStream<SharedLoadIteratorA> SharedLoadStreamA;
- /// The iterator to load B from shared memory.
- typedef TileLoadIterator<typename GemmTileTraitsHelperB::SharedLoadTileTraits,
- typename GemmTileTraitsHelperB::SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorB;
- /// The stream to load B from shared memory.
- typedef SharedLoadStream<SharedLoadIteratorB> SharedLoadStreamB;
-
- /// The functor to do the multiply-add in the main loop.
- typedef typename GemmConfig::MultiplyAdd MultiplyAdd;
- /// The object to clear accumulators.
- typedef ClearAccumulators<typename MultiplyAdd::ScalarC> ClearAccumulators;
-
- /// The traits class for the epilogue.
- typedef SimplifiedGemmEpilogueTraits<GemmConfig, EpilogueFunctor_, Index_> GemmEpilogueTraits;
- /// The epilogue.
- typedef GemmEpilogue<GemmEpilogueTraits> Epilogue;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The output tile.
- typename OutputTile_ = Shape<8, 128, 128>,
- /// The functor to do the math in the epilogue.
- typename EpilogueFunctor_ = LinearScaling<half>,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_ = Shape<8, 8, 16>,
- /// The number of halfs loaded in one LDG for A.
- int kScalarsPerLdgA_ = 2,
- /// The number of halfs loaded in one LDG for B.
- int kScalarsPerLdgB_ = 2,
- /// The index.
- typename Index_ = int,
- /// The helper class.
- typename Helper_ = HgemmTraitsHelper<kLayoutA_,
- kLayoutB_,
- OutputTile_,
- EpilogueFunctor_,
- AccumulatorsPerThread_,
- kScalarsPerLdgA_,
- kScalarsPerLdgB_,
- Index_> >
-struct HgemmTraits : public GemmTraits<
- // The config.
- typename Helper_::GemmConfig,
- // The stream to load A from global memory to shared memory.
- typename Helper_::GlobalLoadStreamA,
- // The stream to load B from global memory to shared memory.
- typename Helper_::GlobalLoadStreamB,
- // The stream to load A from shared memory.
- typename Helper_::SharedLoadStreamA,
- // The stream to load B from shared memory.
- typename Helper_::SharedLoadStreamB,
- // The epilogue.
- typename Helper_::Epilogue,
- // The block swizzle to reorganize the grid.
- IdentityBlockSwizzle,
- // The index.
- Index_,
- // The tool used to clear accumulators.
- typename Helper_::ClearAccumulators> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/identity_block_swizzle.h b/cutlass-example/cutlass/gemm/identity_block_swizzle.h
deleted file mode 100644
index e1bdb2e..0000000
--- a/cutlass-example/cutlass/gemm/identity_block_swizzle.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defies functors for mapping blockIdx to partitions of the GEMM computation.
-
- Currently, we only implement an identity mapping.
-*/
-#pragma once
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-struct IdentityBlockSwizzle {
- /// Ctor.
- CUTLASS_DEVICE IdentityBlockSwizzle() {}
-
- /// Swizzle the block index.
- CUTLASS_DEVICE dim3 swizzle() { return blockIdx; }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/igemm_epilogue.h b/cutlass-example/cutlass/gemm/igemm_epilogue.h
deleted file mode 100644
index 0d69980..0000000
--- a/cutlass-example/cutlass/gemm/igemm_epilogue.h
+++ /dev/null
@@ -1,320 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines the epilogue phase of the GEMM computation for IGEMM, supporting integer and
- floating-point output matrix formats.
-*/
-#pragma once
-
-#include <cutlass/convert.h>
-#include <cutlass/fragment.h>
-#include <cutlass/gemm/gemm_global_stream.h>
-#include <cutlass/gemm/gemm_shared_stream.h>
-#include <cutlass/gemm/igemm_global_tile.h>
-#include <cutlass/reshape_tile.h>
-#include <cutlass/tile_iterator.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <int kElements_>
-struct IgemmFloatToInt8Converter {
- /// The input fragment.
- typedef Fragment<float, kElements_> InputFragment;
- /// The output fragment.
- typedef Fragment<int8_t, kElements_> OutputFragment;
-
- // We are packing 4 floats into int32 registers so we need kElements to be multiple of 4.
- static_assert(kElements_ % 4 == 0, "kElements must be multiple of 4");
-
- /// Ctor.
- CUTLASS_DEVICE IgemmFloatToInt8Converter() {}
-
- /// Transform a fragment.
- CUTLASS_DEVICE void transform(InputFragment const& src, OutputFragment& dst) {
- transform(src, 0, dst);
- }
-
- /// Transform a fragment.
- template <typename Fragment_>
- CUTLASS_DEVICE void transform(Fragment_ const& src, int offset, OutputFragment& dst) {
- // The inputs.
- float4 const* src_f4 = reinterpret_cast<float4 const*>(&src[0]);
- // The outputs.
- int* dst_int = reinterpret_cast<int*>(&dst[0]);
-
- // Iterate over the floats and pack them together to produce ints.
- for (int i = 0; i < kElements_ / 4; ++i) {
- // Read the float4.
- float4 f4 = src_f4[i];
-
- // Clamp the 4 elements of the floats to the [-128, +127] range.
- float x = fmaxf(-128.f, fminf(127.f, f4.x));
- float y = fmaxf(-128.f, fminf(127.f, f4.y));
- float z = fmaxf(-128.f, fminf(127.f, f4.z));
- float w = fmaxf(-128.f, fminf(127.f, f4.w));
-
- // Convert to integers.
- int ix = (int)x;
- int iy = (int)y;
- int iz = (int)z;
- int iw = (int)w;
-
- // Extract the lower bytes to build an int32 with 4 int8.
- asm volatile("prmt.b32 %0, %0, %1, 0x1140;" : "+r"(ix) : "r"(iy));
- asm volatile("prmt.b32 %0, %0, %1, 0x1140;" : "+r"(iz) : "r"(iw));
- asm volatile("prmt.b32 %0, %0, %1, 0x5410;" : "+r"(ix) : "r"(iz));
-
- // Store the int.
- dst_int[i] = ix;
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename InputScalar_, typename OutputFragment_>
-struct IgemmGlobalStoreTransformer {
- typedef Convert<Fragment<InputScalar_, OutputFragment_::kElements>, OutputFragment_> Transformer;
-};
-
-template <int kElements_>
-struct IgemmGlobalStoreTransformer<float, Fragment<int8_t, kElements_> > {
- typedef IgemmFloatToInt8Converter<kElements_> Transformer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <int kElements_>
-struct IgemmInt8ToFloatConverter {
- /// The input fragment.
- typedef Fragment<int8_t, kElements_> InputFragment;
- /// The output fragment.
- typedef Fragment<float, kElements_> OutputFragment;
-
- // We are unpacking 4 int8s from int32.
- static_assert(kElements_ % 4 == 0, "kElements must be multiple of 4");
-
- /// Ctor.
- CUTLASS_DEVICE IgemmInt8ToFloatConverter() {}
-
- /// Transform a fragment.
- CUTLASS_DEVICE void transform(InputFragment const& src, OutputFragment& dst) {
- transform(src, 0, dst);
- }
-
- /// Transform a fragment.
- template <typename Fragment_>
- CUTLASS_DEVICE void transform(Fragment_ const& src, int offset, OutputFragment& dst) {
- // The inputs.
- int const* src_int = reinterpret_cast<int const*>(&src[0]);
- // The outputs.
- float4* dst_f4 = reinterpret_cast<float4*>(&dst[0]);
-
- // Iterate over the int8 and unpack them together to produce floats.
- for (int i = 0; i < kElements_ / 4; ++i) {
- // Read the int.
- int ix, iy, iz, iw = src_int[i];
-
- // Extract the 4 bytes.
- asm volatile("prmt.b32 %0, 0x0, %1, 0x4440;" : "=r"(ix) : "r"(iw));
- asm volatile("prmt.b32 %0, 0x0, %1, 0x4441;" : "=r"(iy) : "r"(iw));
- asm volatile("prmt.b32 %0, 0x0, %1, 0x4442;" : "=r"(iz) : "r"(iw));
- asm volatile("prmt.b32 %0, 0x0, %1, 0x4443;" : "=r"(iw) : "r"(iw));
-
- // The floats.
- float fx, fy, fz, fw;
-
- // Convert to floats (make sure we generate I2F.F32.S8).
- asm volatile("cvt.rn.f32.s8 %0, %1;" : "=f"(fx) : "r"(ix));
- asm volatile("cvt.rn.f32.s8 %0, %1;" : "=f"(fy) : "r"(iy));
- asm volatile("cvt.rn.f32.s8 %0, %1;" : "=f"(fz) : "r"(iz));
- asm volatile("cvt.rn.f32.s8 %0, %1;" : "=f"(fw) : "r"(iw));
-
- // Store the float4.
- dst_f4[i] = make_float4(fx, fy, fz, fw);
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename InputFragment_, typename OutputScalar_>
-struct IgemmGlobalLoadTransformer {
- typedef Convert<InputFragment_, Fragment<OutputScalar_, InputFragment_::kElements> > Transformer;
-};
-
-template <int kElements_>
-struct IgemmGlobalLoadTransformer<Fragment<int8_t, kElements_>, float> {
- typedef IgemmInt8ToFloatConverter<kElements_> Transformer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename InputScalar_, typename OutputFragment_>
-struct IgemmSharedStoreTransformer {
- typedef Convert<Fragment<InputScalar_, OutputFragment_::kElements>, OutputFragment_> Transformer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename IgemmConfig_, typename EpilogueFunctor_, typename Index_>
-struct IgemmEpilogueTraitsHelper
- : public GemmEpilogueTraitsHelper<IgemmConfig_, EpilogueFunctor_, Index_> {
- /// The base class.
- typedef GemmEpilogueTraitsHelper<IgemmConfig_, EpilogueFunctor_, Index_> Base;
- /// The config.
- typedef IgemmConfig_ IgemmConfig;
-
- /// The scalar type of the epilogue.
- typedef typename Base::Scalar Scalar;
- /// The iterations.
- typedef typename Base::Iterations Iterations;
- /// The iterations strides.
- typedef typename Base::Delta Delta;
-
- /// The traits class for the iterator.
- typedef typename Base::GlobalLoadTileTraits GlobalLoadTileTraits;
- /// The iterator to store to shared memory.
- typedef GemmGlobalIteratorCd<GlobalLoadTileTraits> GlobalLoadIteratorC;
- /// The fragment that needs to be produced by the load iterator.
- typedef typename GlobalLoadIteratorC::Fragment GlobalFragmentC;
- /// The transformer from loaded data to math fragment.
- typedef
- typename IgemmGlobalLoadTransformer<GlobalFragmentC, Scalar>::Transformer GlobalTransformerC;
-
- /// The traits class for the iterator.
- typedef typename Base::GlobalStoreTileTraits GlobalStoreTileTraits;
- /// The iterator to store to shared memory.
- typedef GemmGlobalIteratorCd<GlobalStoreTileTraits> GlobalStoreIteratorD;
- /// The fragment that needs to be passed to that store iterator.
- typedef typename GlobalStoreIteratorD::Fragment GlobalFragmentD;
- /// The transformer from accumulators to shared memory fragments.
- typedef
- typename IgemmGlobalStoreTransformer<Scalar, GlobalFragmentD>::Transformer GlobalTransformerD;
-
- /// The traits class for the shared iterator to store D to shared memory.
- typedef typename Base::SharedStoreTileTraits SharedStoreTileTraits;
- /// The shared iterator to store D to shared memory.
- typedef TileStoreIterator<SharedStoreTileTraits,
- typename SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kGlobal>
- SharedStoreIteratorD;
- /// The fragment that needs to be passed to that store iterator.
- typedef typename SharedStoreIteratorD::Fragment SharedStoreFragmentD;
- /// The transformer from accumulators to shared memory fragments.
- typedef typename IgemmSharedStoreTransformer<typename IgemmConfig::Accumulators::Element,
- SharedStoreFragmentD>::Transformer
- SharedStoreTransformerD;
- /// The traits class for the shared iterator to load D from shared memory.
- typedef typename Base::SharedLoadTileTraits SharedLoadTileTraits;
- /// The shared iterator to load D from shared memory.
- typedef TileLoadIterator<SharedLoadTileTraits,
- typename SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorD;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The config.
- typename IgemmConfig_,
- /// The functor to do the math in the epilogue.
- typename EpilogueFunctor_,
- /// The index.
- typename Index_ = int,
- /// The helper class to assemble the traits.
- typename Helper_ = IgemmEpilogueTraitsHelper<IgemmConfig_, EpilogueFunctor_, Index_> >
-struct IgemmEpilogueTraits : public GemmEpilogueTraits<
- // The output tile.
- typename IgemmConfig_::OutputTile,
- // The accumulators.
- typename IgemmConfig_::Accumulators,
- // The global iterator for C.
- typename Helper_::GlobalLoadIteratorC,
- // The transformer for C.
- typename Helper_::GlobalTransformerC,
- // The transformer for D.
- typename Helper_::GlobalTransformerD,
- // The global iterator for D.
- typename Helper_::GlobalStoreIteratorD,
- // The iterator to store D to shared memory.
- typename Helper_::SharedStoreIteratorD,
- // The shared store transformer for D.
- typename Helper_::SharedStoreTransformerD,
- // The iterator to load D from shared memory.
- typename Helper_::SharedLoadIteratorD,
- // The iterations.
- typename Helper_::Iterations,
- // The strides between iterations.
- typename Helper_::Delta,
- // The functor to be used in the epilogue.
- EpilogueFunctor_,
- // The index.
- Index_> {
- /// Do we output in int8?
- static bool const kInt8Output =
- platform::is_same<typename IgemmConfig_::ScalarC, int8_t>::value != 0;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmEpilogueTraits_, bool = GemmEpilogueTraits_::kInt8Output>
-struct IgemmEpilogue : public GemmEpilogue<GemmEpilogueTraits_> {
- /// The base class.
- typedef GemmEpilogue<GemmEpilogueTraits_> Base;
-
- /// Ctor.
- CUTLASS_DEVICE IgemmEpilogue(typename Base::Params const& params_,
- typename Base::SharedStorage& shared_storage_,
- typename Base::Index m_,
- typename Base::Index n_)
- : Base(params_, shared_storage_, m_, n_) {}
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmEpilogueTraits_>
-struct IgemmEpilogue<GemmEpilogueTraits_, true> : public GemmEpilogue<GemmEpilogueTraits_> {
- /// The base class.
- typedef GemmEpilogue<GemmEpilogueTraits_> Base;
-
- /// Ctor.
- CUTLASS_DEVICE IgemmEpilogue(typename Base::Params const& params_,
- typename Base::SharedStorage& shared_storage_,
- typename Base::Index m_,
- typename Base::Index n_)
- : Base(params_, shared_storage_, m_, n_) {}
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/igemm_global_tile.h b/cutlass-example/cutlass/gemm/igemm_global_tile.h
deleted file mode 100644
index 3f594ac..0000000
--- a/cutlass-example/cutlass/gemm/igemm_global_tile.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Implements tile iterators to partition the thread block tile into 2D subtiles and
- efficiently load each. Applies permute transformation to construct 'interleaved K-strided'
- data layout in which 4-element dot products from the same K index are arranged in consecutive
- locations within shared memory.
-
- Supports efficient loads from shared memory to target the DP4A instruction.
-*/
-#pragma once
-
-#include <cutlass/coord.h>
-#include <cutlass/gemm/gemm_global_tile.h>
-#include <cutlass/matrix_traits.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <GemmOperand::Kind kOperand_,
- MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename Tile_,
- typename Threads_,
- int kAccessSize_>
-struct IgemmGlobalTileTraits : public GemmGlobalTileTraits<
- // Which GEMM operand?
- kOperand_,
- // The layout.
- kLayout_,
- // The scalar.
- Scalar_,
- // The tile.
- Tile_,
- // The threads.
- Threads_,
- // The number of scalars per LDG/STG.
- kAccessSize_> {
- /// The base class.
- typedef GemmGlobalTileTraits<kOperand_, kLayout_, Scalar_, Tile_, Threads_, kAccessSize_> Base;
- /// The threads.
- typedef typename Base::Threads Threads;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<Base::Threads::kH * 4, 1, Base::Threads::kW, Base::kAccessSize> Delta;
- /// The number of iterations needed to load/store the tile.
- typedef Shape<Base::Tile::kH / Base::Threads::kH / 4,
- 4,
- Base::Tile::kW / Base::Threads::kW,
- Base::Tile::kC / Base::kAccessSize>
- Iterations;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- int thread_offset_h = threadIdx.x / Threads::kW * ThreadsDelta::kH;
- int thread_offset_w = threadIdx.x % Threads::kW * ThreadsDelta::kW;
-
- return make_Coord(0, thread_offset_h, thread_offset_w, 0);
- }
- };
-
- public:
- /// The threads strides.
- typedef Shape<1, 4, Base::Tile::kC> ThreadsDelta;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Deprecated. Please use IgemmGlobalTileTraits instead.
-
-template <GemmOperand::Kind kOperand_,
- MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename Tile_,
- typename Threads_,
- int kAccessSize_>
-struct IgemmContiguousGlobalTileTraits
- : public IgemmGlobalTileTraits<kOperand_, kLayout_, Scalar_, Tile_, Threads_, kAccessSize_> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename TileTraits_, typename Index_ = int>
-struct IgemmGlobalIteratorAb : public GemmGlobalIteratorAb<TileTraits_, Index_> {
- /// The base class.
- typedef GemmGlobalIteratorAb<TileTraits_, Index_> Base;
- /// The functor to compute the thread offset.
- typedef typename TileTraits_::ThreadOffset ThreadOffset;
-
- /// Constructor.
- CUTLASS_DEVICE IgemmGlobalIteratorAb(typename Base::Params const& _params,
- const Coord<3>& bounds,
- const Coord<3>& block,
- ThreadOffset thread_offset_func = ThreadOffset())
- : Base(_params, bounds, block, thread_offset_func), in_residue_(false), mask_(0xffffffff) {
- // The number of elements read in a single iteration.
- int const kBlock = TileTraits_::Tile::kW * TileTraits_::kAccessSize;
- // The residue.
- int const kResidue = (int)(bounds[1] % kBlock);
-
- // Compute the number of elements that are valid.
- int const left = kResidue - Base::thread_offset[2];
- if (left > 0 && left < 4) {
- mask_ = (1u << (8 * left)) - 1u;
- }
- }
-
- /// The accessor.
- CUTLASS_DEVICE void get(typename Base::AccessType& value, int d, int h, int w, int c) const {
- Base::get(value, d, h, w, c);
- if (in_residue_) {
- reinterpret_cast<uint32_t&>(value) &= mask_;
- }
- }
-
- /// Move to residue portion.
- CUTLASS_DEVICE void move_to_residue(typename Base::Index k) {
- Base::move_to_residue(k);
- in_residue_ = true;
- }
-
- /// Move back to the beginning of the first tile.
- CUTLASS_DEVICE void rollback() {
- Base::rollback();
- in_residue_ = false;
- }
-
- /// Are we in the residue?
- bool in_residue_;
- /// The mask to clean up the values.
- uint32_t mask_;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/igemm_multiply_add.h b/cutlass-example/cutlass/gemm/igemm_multiply_add.h
deleted file mode 100644
index 5a8baec..0000000
--- a/cutlass-example/cutlass/gemm/igemm_multiply_add.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Implements matrix multiply accumulate operation of 8-bit integer data using DP4A
- instruction.
-*/
-#pragma once
-
-#include <cutlass/fragment.h>
-
-#include <cutlass/gemm/thread_multiply_add.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Template performing matrix multiply-add operation within a thread
-template <typename AccumulatorsPerThread_, typename ThreadsPerWarp_>
-struct ThreadMultiplyAdd<AccumulatorsPerThread_, ThreadsPerWarp_, int8_t, int8_t, int> {
- /// The shape of the instruction.
- typedef Shape<4, 1, 1> InstructionShape;
- /// The number of accumulators per thread.
- typedef AccumulatorsPerThread_ AccumulatorsPerThread;
- /// The number of threads per warp.
- typedef ThreadsPerWarp_ ThreadsPerWarp;
- /// The number of accumulators per warp.
- typedef typename ShapeMul<AccumulatorsPerThread, ThreadsPerWarp>::Shape AccumulatorsPerWarp;
- /// The type for A.
- typedef int8_t ScalarA;
- /// The fragment for A.
- typedef Fragment<ScalarA, AccumulatorsPerThread::kW * 4> FragmentA;
- /// The type for B.
- typedef int8_t ScalarB;
- /// The fragment for B.
- typedef Fragment<ScalarB, AccumulatorsPerThread::kH * 4> FragmentB;
- /// The type for C and D.
- typedef int ScalarC;
- /// The accumulators.
- typedef Fragment<ScalarC, AccumulatorsPerThread::kH * AccumulatorsPerThread::kW> Accumulators;
-
- /// Ctor.
- CUTLASS_DEVICE ThreadMultiplyAdd() {}
-
- /// Multiply : d = a*b + c.
- CUTLASS_DEVICE void multiply_add(FragmentA const& a,
- FragmentB const& b,
- Accumulators const& c,
- Accumulators& d) {
- // The inputs.
- int const* a_int = reinterpret_cast<int const*>(&a[0]);
- int const* b_int = reinterpret_cast<int const*>(&b[0]);
-
- for (int j = 0; j < AccumulatorsPerThread::kH; ++j) {
- for (int i = 0; i < AccumulatorsPerThread::kW; ++i) {
- asm volatile("dp4a.s32.s32 %0, %1, %2, %3;"
- : "=r"(d[j * AccumulatorsPerThread::kW + i])
- : "r"(a_int[i]), "r"(b_int[j]), "r"(c[j * AccumulatorsPerThread::kW + i]));
- }
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/igemm_swizzle.h b/cutlass-example/cutlass/gemm/igemm_swizzle.h
deleted file mode 100644
index 77cf711..0000000
--- a/cutlass-example/cutlass/gemm/igemm_swizzle.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Transposes a fragment of data containing packed 8-bit integer elements.
-*/
-#pragma once
-
-#include <cutlass/fragment.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GlobalIterator_>
-struct IgemmSwizzle {
- /// The global iterator.
- typedef GlobalIterator_ GlobalIterator;
- /// The source fragment.
- typedef typename GlobalIterator::Fragment Fragment;
- /// The shape of the source fragment.
- typedef typename GlobalIterator::FragmentShape FragmentShape;
-
- /// The source fragment.
- typedef Fragment InputFragment;
- /// The destination fragment.
- typedef Fragment OutputFragment;
-
- /// The src/dst must be int8 fragments.
- static_assert((platform::is_same<typename Fragment::Element, int8_t>::value), "Works on int8");
-
- /// The number of elements must be a multiple of 4.
- static_assert(FragmentShape::kH % 4 == 0 && ShapeCount<FragmentShape>::kWc % 4 == 0,
- "Not multiple of 4");
-
- /// Ctor.
- CUTLASS_DEVICE IgemmSwizzle() {}
-
- /// Transform a fragment.
- CUTLASS_DEVICE void transform(Fragment const& src, Fragment& dst) {
- // Expose src/dst as int arrays.
- int const* src_int = reinterpret_cast<int const*>(&src[0]);
- int* dst_int = reinterpret_cast<int*>(&dst[0]);
-
- // Transpose the data.
- for (int d = 0; d < FragmentShape::kD; ++d) {
- for (int h = 0; h < FragmentShape::kH / 4; ++h) {
- for (int w = 0; w < ShapeCount<FragmentShape>::kWc / 4; ++w) {
- int const i0 = d * (ShapeCount<FragmentShape>::kHwc / 4) +
- (4 * h + 0) * (ShapeCount<FragmentShape>::kWc / 4) + w;
- int const i1 = d * (ShapeCount<FragmentShape>::kHwc / 4) +
- (4 * h + 1) * (ShapeCount<FragmentShape>::kWc / 4) + w;
- int const i2 = d * (ShapeCount<FragmentShape>::kHwc / 4) +
- (4 * h + 2) * (ShapeCount<FragmentShape>::kWc / 4) + w;
- int const i3 = d * (ShapeCount<FragmentShape>::kHwc / 4) +
- (4 * h + 3) * (ShapeCount<FragmentShape>::kWc / 4) + w;
-
- int a0 = src_int[i0];
- int a1 = src_int[i1];
- int a2 = src_int[i2];
- int a3 = src_int[i3];
-
- int b0, b1, b2, b3, c0;
- asm volatile("prmt.b32 %0, %1, %2, 0x0040;" : "=r"(b0) : "r"(a0), "r"(a1));
- asm volatile("prmt.b32 %0, %1, %2, 0x0040;" : "=r"(c0) : "r"(a2), "r"(a3));
- asm volatile("prmt.b32 %0, %1, %2, 0x5410;" : "=r"(b0) : "r"(b0), "r"(c0));
-
- asm volatile("prmt.b32 %0, %1, %2, 0x0051;" : "=r"(b1) : "r"(a0), "r"(a1));
- asm volatile("prmt.b32 %0, %1, %2, 0x0051;" : "=r"(c0) : "r"(a2), "r"(a3));
- asm volatile("prmt.b32 %0, %1, %2, 0x5410;" : "=r"(b1) : "r"(b1), "r"(c0));
-
- asm volatile("prmt.b32 %0, %1, %2, 0x0062;" : "=r"(b2) : "r"(a0), "r"(a1));
- asm volatile("prmt.b32 %0, %1, %2, 0x0062;" : "=r"(c0) : "r"(a2), "r"(a3));
- asm volatile("prmt.b32 %0, %1, %2, 0x5410;" : "=r"(b2) : "r"(b2), "r"(c0));
-
- asm volatile("prmt.b32 %0, %1, %2, 0x0073;" : "=r"(b3) : "r"(a0), "r"(a1));
- asm volatile("prmt.b32 %0, %1, %2, 0x0073;" : "=r"(c0) : "r"(a2), "r"(a3));
- asm volatile("prmt.b32 %0, %1, %2, 0x5410;" : "=r"(b3) : "r"(b3), "r"(c0));
-
- dst_int[i0] = b0;
- dst_int[i1] = b1;
- dst_int[i2] = b2;
- dst_int[i3] = b3;
- }
- }
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/igemm_traits.h b/cutlass-example/cutlass/gemm/igemm_traits.h
deleted file mode 100644
index 82f8de5..0000000
--- a/cutlass-example/cutlass/gemm/igemm_traits.h
+++ /dev/null
@@ -1,539 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defies structural properties of mixed-precision integer GEMM. Multiplicands are assumed
- to be packed 8bit integers, accumulators are assumed to be 32b signed integers, and output
- formats vary.
-*/
-#pragma once
-
-#include <cutlass/convert.h>
-#include <cutlass/gemm/gemm.h>
-#include <cutlass/gemm/gemm_epilogue.h>
-#include <cutlass/gemm/gemm_epilogue_traits.h>
-#include <cutlass/gemm/gemm_global_tile.h>
-#include <cutlass/gemm/gemm_shared_tile.h>
-#include <cutlass/gemm/gemm_traits.h>
-#include <cutlass/gemm/igemm_epilogue.h>
-#include <cutlass/gemm/igemm_global_tile.h>
-#include <cutlass/gemm/igemm_multiply_add.h>
-#include <cutlass/gemm/igemm_swizzle.h>
-#include <cutlass/reshape_tile.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The tile size for the GEMM KxNxM.
- typename OutputTile_,
- /// The output type.
- typename ScalarD_,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_>
-struct IgemmConfig
- : public GemmConfig<
- /// The scalar type for A.
- int8_t,
- /// The scalar type for B.
- int8_t,
- /// The scalar type for C.
- ScalarD_,
- /// The scalar type for D.
- ScalarD_,
- /// The tile size for the GEMM KxNxM.
- OutputTile_,
- /// The functor to do the math in the main loop.
- ThreadMultiplyAdd<AccumulatorsPerThread_, Shape<1, 4, 8>, int8_t, int8_t, int>,
- /// The number of scalars per LDG for A.
- 4,
- /// The number of scalars per STS for A.
- 4,
- /// The number of scalars per LDS for A.
- 16,
- /// The number of scalars per LDG for B.
- 4,
- /// The number of scalars per STS for B.
- 4,
- /// The number of scalars per LDS for B.
- 16,
- /// The number of scalars per LDG for C and STG for D.
- 1,
- /// The number of scalars per STS for D.
- 4,
- /// The number of scalars per LDS for D.
- 1,
- /// The number of stages in shared memory.
- 2,
- /// Enable the code path that deals with the residue in epilogue.
- true> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename OutputTile_, typename AccumulatorsPerThread_>
-struct IgemmConfig<OutputTile_, int8_t, AccumulatorsPerThread_>
- : public GemmConfig<
- /// The scalar type for A.
- int8_t,
- /// The scalar type for B.
- int8_t,
- /// The scalar type for C.
- int8_t,
- /// The scalar type for D.
- int8_t,
- /// The tile size for the GEMM KxNxM.
- OutputTile_,
- /// The functor to do the math in the main loop.
- ThreadMultiplyAdd<AccumulatorsPerThread_, Shape<1, 4, 8>, int8_t, int8_t, int>,
- /// The number of scalars per LDG for A.
- 4,
- /// The number of scalars per STS for A.
- 4,
- /// The number of scalars per LDS for A.
- 16,
- /// The number of scalars per LDG for B.
- 4,
- /// The number of scalars per STS for B.
- 4,
- /// The number of scalars per LDS for B.
- 16,
- /// The number of scalars per LDG for C and STG for D.
- 4,
- /// The number of scalars per STS for D.
- 4,
- /// The number of scalars per LDS for D.
- 4,
- /// The number of stages in shared memory.
- 2,
- /// Enable the code path that deals with the residue in epilogue.
- true> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename GemmConfig_, typename Index_>
-struct IgemmTileTraitsHelperA : public GemmTileTraitsHelperA<kLayout_, GemmConfig_> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_, typename Index_>
-struct IgemmTileTraitsHelperA<MatrixLayout::kColumnMajor, GemmConfig_, Index_>
- : public GemmTileTraitsHelperA<MatrixLayout::kColumnMajor, GemmConfig_> {
- /// The base config.
- typedef GemmTileTraitsHelperA<MatrixLayout::kColumnMajor, GemmConfig_> Base;
-
- /// The number of scalars per LDG/STS/LDS for A.
- static int const kScalarsPerStsA = 16;
-
- /// The traits class to build the iterator to load data from global memory for A^N.
- typedef IgemmGlobalTileTraits<
- GemmOperand::kA,
- // The layout.
- MatrixLayout::kColumnMajor,
- // The pointer is float const.
- int8_t const,
- // The tile has size KxM in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kW>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgA>
- GlobalTileTraits;
-
- // The iterator.
- typedef GemmGlobalIteratorAb<GlobalTileTraits, Index_> GlobalLoadIterator;
-
- /// The traits class to build the iterator to store data to shared memory for A^N.
- typedef GemmSharedStoreTileAbTraits<
- // The pointer is float.
- int8_t,
- // The tile has size KxM in GEMM's terminology.
- Shape<GemmConfig_::kStages, GemmConfig_::OutputTile::kD / 4, GemmConfig_::OutputTile::kW * 4>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- kScalarsPerStsA>
- SharedStoreTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_, typename Index_>
-struct IgemmTileTraitsHelperA<MatrixLayout::kRowMajor, GemmConfig_, Index_> {
- /// The layout.
- static MatrixLayout::Kind const kLayout = MatrixLayout::kRowMajor;
-
- /// The input scalar.
- typedef int8_t Scalar;
- /// The scalar stored in shared memory.
- typedef int8_t MultiplyAddScalar;
-
- /// The number of scalars per LDG/STS/LDS for A.
- static int const kScalarsPerStsA = 16;
-
- /// The traits class to build the iterator to load data from global memory for A^T.
- typedef IgemmGlobalTileTraits<
- GemmOperand::kA,
- // The layout.
- MatrixLayout::kRowMajor,
- // The pointer is float const.
- int8_t const,
- // The tile has size NxK in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kW, GemmConfig_::OutputTile::kD>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgA>
- GlobalTileTraits;
-
- // The iterator.
- typedef IgemmGlobalIteratorAb<GlobalTileTraits, Index_> GlobalLoadIterator;
-
- /// The traits class to build the iterator to store data to shared memory for A^N.
- typedef GemmSharedStoreWithSkewTileAbTraits<
- // The pointer is int8.
- int8_t,
- // The tile has size KxN in GEMM's terminology.
- Shape<GemmConfig_::kStages, GemmConfig_::OutputTile::kD / 4, GemmConfig_::OutputTile::kW * 4>,
- // The threads are distributed as (threads / K) x K (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS.
- kScalarsPerStsA,
- // The skew to avoid bank conflicts added in the tile W dimension.
- 16>
- SharedStoreTileTraits;
-
- /// The traits class to build the iterator to load from shared memory for A^N.
- typedef GemmSharedLoadTileATraits<
- // The pointer is float const.
- int8_t const,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The shape of the FMA instruction.
- typename GemmConfig_::InstructionShape,
- // The number of stages.
- GemmConfig_::kStages,
- // The number of scalars per LDS.
- 16,
- // The skew.
- SharedStoreTileTraits::kSkew>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename GemmConfig_, typename Index_>
-struct IgemmTileTraitsHelperB : public GemmTileTraitsHelperB<kLayout_, GemmConfig_> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_, typename Index_>
-struct IgemmTileTraitsHelperB<MatrixLayout::kColumnMajor, GemmConfig_, Index_> {
- /// The layout.
- static MatrixLayout::Kind const kLayout = MatrixLayout::kColumnMajor;
-
- /// The input scalar.
- typedef int8_t Scalar;
- /// The scalar stored in shared memory.
- typedef int8_t MultiplyAddScalar;
-
- /// The number of scalars per LDG/STS/LDS for B.
- static int const kScalarsPerStsB = 16;
-
- /// The traits class to build the iterator to load data from global memory for B^T.
- typedef IgemmGlobalTileTraits<
- GemmOperand::kB,
- // The layout.
- MatrixLayout::kColumnMajor,
- // The pointer is float const.
- int8_t const,
- // The tile has size NxK in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kH, GemmConfig_::OutputTile::kD>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgB>
- GlobalTileTraits;
-
- // The iterator.
- typedef IgemmGlobalIteratorAb<GlobalTileTraits, Index_> GlobalLoadIterator;
-
- /// The traits class to build the iterator to store data to shared memory for B^N.
- typedef GemmSharedStoreWithSkewTileAbTraits<
- // The pointer is int8.
- int8_t,
- // The tile has size KxN in GEMM's terminology.
- Shape<GemmConfig_::kStages, GemmConfig_::OutputTile::kD / 4, GemmConfig_::OutputTile::kH * 4>,
- // The threads are distributed as (threads / K) x K (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS.
- kScalarsPerStsB,
- // The skew to avoid bank conflicts added in the tile W dimension.
- 16>
- SharedStoreTileTraits;
-
- /// The traits class to build the iterator to load from shared memory for B^N.
- typedef GemmSharedLoadTileBTraits<
- // The pointer is float const.
- int8_t const,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The number of threads per warp.
- typename GemmConfig_::MultiplyAdd::ThreadsPerWarp,
- // The shape of the FMA instruction.
- typename GemmConfig_::InstructionShape,
- // The number of stages.
- GemmConfig_::kStages,
- // The number of scalars per LDS.
- 16,
- // The skew.
- SharedStoreTileTraits::kSkew>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_, typename Index_>
-struct IgemmTileTraitsHelperB<MatrixLayout::kRowMajor, GemmConfig_, Index_>
- : public GemmTileTraitsHelperB<MatrixLayout::kRowMajor, GemmConfig_> {
- /// The base config.
- typedef GemmTileTraitsHelperB<MatrixLayout::kRowMajor, GemmConfig_> Base;
-
- /// The number of scalars per LDG/STS/LDS for B.
- static int const kScalarsPerStsB = 16;
-
- /// The traits class to build the iterator to load data from global memory for B^T.
- typedef IgemmGlobalTileTraits<
- GemmOperand::kB,
- // The layout.
- MatrixLayout::kRowMajor,
- // The pointer is float const.
- int8_t const,
- // The tile has size KxM in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kH>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgB>
- GlobalTileTraits;
-
- // The iterator.
- typedef GemmGlobalIteratorAb<GlobalTileTraits, Index_> GlobalLoadIterator;
-
- /// The traits class to build the iterator to store data to shared memory for B^N.
- typedef GemmSharedStoreTileAbTraits<
- // The pointer is float.
- int8_t,
- // The tile has size KxM in GEMM's terminology.
- Shape<GemmConfig_::kStages, GemmConfig_::OutputTile::kD / 4, GemmConfig_::OutputTile::kH * 4>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- kScalarsPerStsB>
- SharedStoreTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename Iterator_>
-struct IgemmTransformerA {};
-
-template <typename Iterator_>
-struct IgemmTransformerA<MatrixLayout::kRowMajor, Iterator_> {
- typedef Copy<typename Iterator_::Fragment> Transformer;
-};
-
-template <typename Iterator_>
-struct IgemmTransformerA<MatrixLayout::kColumnMajor, Iterator_> {
- typedef IgemmSwizzle<Iterator_> Transformer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename Iterator_>
-struct IgemmTransformerB {};
-
-template <typename Iterator_>
-struct IgemmTransformerB<MatrixLayout::kColumnMajor, Iterator_> {
- typedef Copy<typename Iterator_::Fragment> Transformer;
-};
-
-template <typename Iterator_>
-struct IgemmTransformerB<MatrixLayout::kRowMajor, Iterator_> {
- typedef IgemmSwizzle<Iterator_> Transformer;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The output tile.
- typename OutputTile_,
- /// The output type.
- typename ScalarD_,
- /// The functor to do the math in the epilogue.
- typename EpilogueFunctor_,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_ = Shape<32, 8, 8>,
- /// The index.
- typename Index_ = int>
-struct IgemmTraitsHelper {
- /// The IGEMM config.
- typedef IgemmConfig<OutputTile_, ScalarD_, AccumulatorsPerThread_> GemmConfig;
- /// The GEMM config for A.
- typedef IgemmTileTraitsHelperA<kLayoutA_, GemmConfig, Index_> GemmTileTraitsHelperA;
- /// The GEMM config for B.
- typedef IgemmTileTraitsHelperB<kLayoutB_, GemmConfig, Index_> GemmTileTraitsHelperB;
-
- /// The iterator to load A from global memory.
- typedef typename GemmTileTraitsHelperA::GlobalLoadIterator GlobalLoadIteratorA;
-
- /// The default transformer for A.
- typedef typename IgemmTransformerA<GemmTileTraitsHelperA::kLayout,
- GlobalLoadIteratorA>::Transformer GlobalTransformerA;
- /// The iterator to store A to shared memory.
- typedef TileStoreIterator<typename GemmTileTraitsHelperA::SharedStoreTileTraits,
- typename GemmTileTraitsHelperA::SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorA;
- /// The stream to load A from global memory to shared memory.
- typedef GlobalLoadStream<GlobalLoadIteratorA, SharedStoreIteratorA, GlobalTransformerA>
- GlobalLoadStreamA;
-
- /// The iterator to load B from global memory.
- typedef typename GemmTileTraitsHelperB::GlobalLoadIterator GlobalLoadIteratorB;
-
- // The default transformer for B.
- typedef typename IgemmTransformerB<GemmTileTraitsHelperB::kLayout,
- GlobalLoadIteratorB>::Transformer GlobalTransformerB;
- /// The iterator to store B to shared memory.
- typedef TileStoreIterator<typename GemmTileTraitsHelperB::SharedStoreTileTraits,
- typename GemmTileTraitsHelperB::SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorB;
- /// The stream to load B from global memory to shared memory.
- typedef GlobalLoadStream<GlobalLoadIteratorB, SharedStoreIteratorB, GlobalTransformerB>
- GlobalLoadStreamB;
-
- /// The iterator to load A from shared memory.
- typedef TileLoadIterator<typename GemmTileTraitsHelperA::SharedLoadTileTraits,
- typename GemmTileTraitsHelperA::SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorA;
- /// The stream to load A from shared memory.
- typedef SharedLoadStream<SharedLoadIteratorA, Copy<typename SharedLoadIteratorA::Fragment> >
- SharedLoadStreamA;
- /// The iterator to load B from shared memory.
- typedef TileLoadIterator<typename GemmTileTraitsHelperB::SharedLoadTileTraits,
- typename GemmTileTraitsHelperB::SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorB;
- /// The stream to load B from shared memory.
- typedef SharedLoadStream<SharedLoadIteratorB, Copy<typename SharedLoadIteratorB::Fragment> >
- SharedLoadStreamB;
-
- /// The multiply-add functor.
- typedef typename GemmConfig::MultiplyAdd MultiplyAdd;
- /// The object to clear accumulators.
- typedef ClearAccumulators<typename MultiplyAdd::ScalarC> ClearAccumulators;
-
- /// The epilogue.
- typedef IgemmEpilogue<IgemmEpilogueTraits<GemmConfig, EpilogueFunctor_> > Epilogue;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename ScalarD_>
-struct IgemmEpilogueScalar {
- typedef float Scalar;
-};
-
-template <>
-struct IgemmEpilogueScalar<int> {
- typedef int Scalar;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The output tile.
- typename OutputTile_ = Shape<32, 128, 128>,
- /// The output type.
- typename ScalarD_ = int,
- /// The functor to do the math in the epilogue.
- typename EpilogueFunctor_ = LinearScaling<typename IgemmEpilogueScalar<ScalarD_>::Scalar>,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_ = Shape<32, 8, 8>,
- /// The index.
- typename Index_ = int,
- /// The helper class.
- typename Helper_ = IgemmTraitsHelper<kLayoutA_,
- kLayoutB_,
- OutputTile_,
- ScalarD_,
- EpilogueFunctor_,
- AccumulatorsPerThread_,
- Index_> >
-struct IgemmTraits : public GemmTraits<
- // The config.
- typename Helper_::GemmConfig,
- // The stream to load A from global memory to shared memory.
- typename Helper_::GlobalLoadStreamA,
- // The stream to load B from global memory to shared memory.
- typename Helper_::GlobalLoadStreamB,
- // The stream to load A from shared memory.
- typename Helper_::SharedLoadStreamA,
- // The stream to load B from shared memory.
- typename Helper_::SharedLoadStreamB,
- // The epilogue.
- typename Helper_::Epilogue,
- // The block swizzle to reorganize the grid.
- IdentityBlockSwizzle,
- // The index.
- Index_,
- // The tool used to clear accumulators.
- typename Helper_::ClearAccumulators> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/linear_scaling.h b/cutlass-example/cutlass/gemm/linear_scaling.h
deleted file mode 100644
index 979c93f..0000000
--- a/cutlass-example/cutlass/gemm/linear_scaling.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Implements the BLAS linear scaling function alpha*AB + beta*C
-*/
-#pragma once
-
-#include <cutlass/fragment_multiply_add.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Functor to compute linear combination of fragments
-template <typename Scalar_, typename FragmentMultiplyAdd_ = FragmentMultiplyAdd<Scalar_> >
-struct LinearScaling {
- // The scalar.
- typedef Scalar_ Scalar;
- // The adapater.
- typedef FragmentMultiplyAdd_ FragmentMultiplyAdd;
-
- /// The parameters.
- struct Params {
- /// The alpha/beta scaling params.
- Scalar alpha, beta;
-
- /// Initialize the parameters.
- template <typename GemmDesc_>
- CUTLASS_HOST_DEVICE int initialize(GemmDesc_ const& desc) {
- alpha = desc.alpha;
- beta = desc.beta;
- return 0;
- }
- };
-
- /// Ctor.
- CUTLASS_DEVICE LinearScaling(Params const& params) : alpha(params.alpha), beta(params.beta) {}
-
- /// Evaluate the functor.
- template <typename FragmentA_, typename FragmentB_>
- CUTLASS_DEVICE void evaluate(FragmentA_ const& accum, FragmentB_& output) {
- FragmentMultiplyAdd mad;
- mad.multiply(alpha, accum, output);
- }
-
- /// Evaluate the functor.
- template <typename FragmentA_, typename FragmentB_>
- CUTLASS_DEVICE void evaluate(FragmentA_ const& accum, FragmentB_ const& old, FragmentB_& output) {
- FragmentMultiplyAdd mad;
- FragmentB_ tmp;
- mad.multiply(beta, old, tmp);
- mad.multiply_add(alpha, accum, tmp, output);
- }
-
- /// The alpha/beta scaling factors.
- Scalar alpha, beta;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/sgemm_traits.h b/cutlass-example/cutlass/gemm/sgemm_traits.h
deleted file mode 100644
index 66b7677..0000000
--- a/cutlass-example/cutlass/gemm/sgemm_traits.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defies structural properties of single-precision GEMM.
-*/
-#pragma once
-
-#include <cutlass/gemm/gemm.h>
-#include <cutlass/gemm/gemm_epilogue.h>
-#include <cutlass/gemm/gemm_epilogue_traits.h>
-#include <cutlass/gemm/gemm_global_tile.h>
-#include <cutlass/gemm/gemm_shared_tile.h>
-#include <cutlass/gemm/gemm_traits.h>
-#include <cutlass/gemm/thread_multiply_add.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The tile size for the GEMM KxNxM.
- typename OutputTile_,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_,
- /// The number of scalars per LDG for A.
- int kScalarsPerLdgA_ = 1,
- /// The number of scalars per LDG for B.
- int kScalarsPerLdgB_ = 1>
-struct SgemmConfig
- : public GemmConfig<
- /// The scalar type for A.
- float,
- /// The scalar type for B.
- float,
- /// The scalar type for C.
- float,
- /// The scalar type for D.
- float,
- /// The tile size for the GEMM KxNxM.
- OutputTile_,
- /// The functor to do the math in the main loop.
- ThreadMultiplyAdd<AccumulatorsPerThread_, Shape<1, 4, 8>, float, float, float>,
- /// The number of scalars per LDG for A.
- kScalarsPerLdgA_,
- /// The number of scalars per STS for A.
- kScalarsPerLdgA_,
- /// The number of scalars per LDS for A.
- 4,
- /// The number of scalars per LDG for B.
- kScalarsPerLdgB_,
- /// The number of scalars per STS for B.
- kScalarsPerLdgB_,
- /// The number of scalars per LDS for B.
- 4,
- /// The number of scalars per LDG for C and STG for D.
- 1,
- /// The number of scalars per STS for D.
- 4,
- /// The number of scalars per LDS for D.
- 1,
- /// The number of stages in shared memory.
- 2> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The output tile.
- typename OutputTile_ = Shape<8, 128, 128>,
- /// The functor to use in the epilogue.
- typename EpilogueFunctor_ = LinearScaling<float>,
- /// The number of accumulators per thread.
- typename AccumulatorsPerThread_ = Shape<8, 8, 8>,
- /// The number of floats loaded in one LDG for A.
- int kScalarsPerLdgA_ = 1,
- /// The number of floats loaded in one LDG for B.
- int kScalarsPerLdgB_ = 1,
- /// The index.
- typename Index_ = int,
- /// The SGEMM config.
- typename GemmConfig_ =
- SgemmConfig<OutputTile_, AccumulatorsPerThread_, kScalarsPerLdgA_, kScalarsPerLdgB_>,
- /// The traits class for the epilogue.
- typename GemmEpilogueTraits_ =
- SimplifiedGemmEpilogueTraits<GemmConfig_, EpilogueFunctor_, Index_> >
-struct SgemmTraits : public SimplifiedGemmTraits<
- // The layout for A.
- kLayoutA_,
- // The layout for B.
- kLayoutB_,
- // The config.
- GemmConfig_,
- // The epilogue.
- GemmEpilogue<GemmEpilogueTraits_>,
- // The index.
- Index_> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/thread_multiply_add.h b/cutlass-example/cutlass/gemm/thread_multiply_add.h
deleted file mode 100644
index 20dca15..0000000
--- a/cutlass-example/cutlass/gemm/thread_multiply_add.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Template implementing matrix multiply-add operations on fragments.
-*/
-#pragma once
-
-#include <cutlass/fragment.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Template performing matrix multiply-add operation within a thread
-template <typename AccumulatorsPerThread_,
- typename ThreadsPerWarp_,
- typename ScalarA_,
- typename ScalarB_,
- typename ScalarC_>
-struct ThreadMultiplyAdd {
- /// The shape of the instruction.
- typedef Shape<1, 1, 1, 1> InstructionShape;
- /// The number of accumulators per thread.
- typedef AccumulatorsPerThread_ AccumulatorsPerThread;
- /// The number of threads per warp.
- typedef ThreadsPerWarp_ ThreadsPerWarp;
- /// The number of accumulators per warp.
- typedef typename ShapeMul<AccumulatorsPerThread, ThreadsPerWarp>::Shape AccumulatorsPerWarp;
- /// The type for A.
- typedef ScalarA_ ScalarA;
- /// The fragment for A.
- typedef Fragment<ScalarA, AccumulatorsPerThread::kW> FragmentA;
- /// The type for B.
- typedef ScalarB_ ScalarB;
- /// The fragment for B.
- typedef Fragment<ScalarB, AccumulatorsPerThread::kH> FragmentB;
- /// The type for C and D.
- typedef ScalarC_ ScalarC;
- /// The accumulators.
- typedef Fragment<ScalarC, AccumulatorsPerThread::kH * AccumulatorsPerThread::kW, 16> Accumulators;
-
- /// Ctor.
- CUTLASS_DEVICE ThreadMultiplyAdd() {}
-
- /// Multiply : d = a*b + c.
- CUTLASS_DEVICE void multiply_add(FragmentA const& a,
- FragmentB const& b,
- Accumulators const& c,
- Accumulators& d) {
- for (int j = 0; j < AccumulatorsPerThread::kH; ++j) {
- for (int i = 0; i < AccumulatorsPerThread::kW; ++i) {
- d[j * AccumulatorsPerThread::kW + i] = a[i] * b[j] + c[j * AccumulatorsPerThread::kW + i];
- }
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/wmma_gemm_epilogue_traits.h b/cutlass-example/cutlass/gemm/wmma_gemm_epilogue_traits.h
deleted file mode 100644
index 0fafacf..0000000
--- a/cutlass-example/cutlass/gemm/wmma_gemm_epilogue_traits.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines structural properties of WMMA GEMM's epilogue phase.
-*/
-#pragma once
-
-#include <cutlass/wmma_matrix.h>
-#ifdef CUTLASS_USE_WMMA_API
-
-#include <cutlass/convert.h>
-#include <cutlass/coord.h>
-#include <cutlass/gemm/gemm_global_stream.h>
-#include <cutlass/gemm/gemm_shared_stream.h>
-#include <cutlass/gemm/linear_scaling.h>
-#include <cutlass/gemm/wmma_gemm_global_tile.h>
-#include <cutlass/gemm/wmma_gemm_shared_tile.h>
-#include <cutlass/reshape_tile.h>
-#include <cutlass/tile_iterator.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_, typename EpilogueFunctor_, typename Index_ = int>
-struct WmmaGemmEpilogueTraitsHelper {
- /// The scalar.
- typedef typename EpilogueFunctor_::Scalar Scalar;
- /// The output tile.
- typedef typename GemmConfig_::OutputTile OutputTile;
-
- /// The number of WMMAs in the H dimension.
- static int const kWmmasPerH =
- GemmConfig_::AccumulatorsPerWarp::kH / GemmConfig_::InstructionShape::kH;
- /// The number of iterations in the epilogue. That's the number of "horizontal" WMMAs.
- typedef Shape<1, 1, kWmmasPerH> Iterations;
- // The iteration strides in the H/W dimension.
- typedef Shape<0, 0, 0> Delta;
- /// The functor to do the math in the epilogue.
- typedef EpilogueFunctor_ Functor;
-
- /// The traits class to build the iterator to store to shared memory for D.
- typedef WmmaGemmSharedStoreTileDTraits<
- // The output layout.
- MatrixLayout::kColumnMajor,
- // The pointer is float.
- typename Functor::Scalar,
- // The output tile size.
- typename GemmConfig_::OutputTile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The shape of the instruction.
- typename GemmConfig_::InstructionShape>
- SharedStoreTileTraits;
-
- typedef WmmaMatrix<GemmOperand::kC,
- MatrixLayout::kColumnMajor,
- Scalar,
- typename GemmConfig_::InstructionShape>
- WmmaMatrix;
-
- /// The iterator to store D to shared memory.
- typedef TileStoreIterator<SharedStoreTileTraits,
- typename SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared,
- Index_,
- WmmaMatrix,
- IteratorFragment::kWmmaMatrix>
- SharedStoreIteratorD;
-
- /// The shared store transformer for D.
- typedef Copy<typename SharedStoreIteratorD::Fragment> SharedStoreTransformerD;
-
- /// The traits class to build the iterator to load from shared memory for D.
- typedef WmmaGemmSharedLoadTileDTraits<
- // The pointer.
- typename Functor::Scalar,
- // The tile size.
- typename SharedStoreIteratorD::Tile,
- // The number of threads.
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDS.
- GemmConfig_::kScalarsPerLdsD>
- SharedLoadTileTraits;
-
- /// The iterator to load D from shared memory.
- typedef TileLoadIterator<SharedLoadTileTraits,
- typename SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedLoadIteratorD;
-
- /// The traits class to build the iterator to load data from global memory for C^N.
- typedef WmmaGemmGlobalIteratorCdTraits<
- // The pointer is float const.
- typename GemmConfig_::ScalarC const,
- // The tile has size (N / Iterations)xM in GEMM's terminology.
- Shape<1,
- GemmConfig_::OutputTile::kH / ShapeCount<Iterations>::kCount,
- GemmConfig_::OutputTile::kW>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgC>
- GlobalLoadTileTraits;
-
- /// The iterator to load C.
- typedef WmmaGemmGlobalIteratorCd<GlobalLoadTileTraits, Index_> GlobalLoadIteratorC;
- /// The transformer for C.
- typedef Copy<typename GlobalLoadIteratorC::Fragment> GlobalTransformerC;
-
- /// The traits class to build the iterator to store data to global memory for D^N.
- typedef WmmaGemmGlobalIteratorCdTraits<
- // The pointer is float.
- typename GemmConfig_::ScalarD,
- // The tile has size (N / Iterations)xM in GEMM's terminology.
- Shape<1,
- GemmConfig_::OutputTile::kH / ShapeCount<Iterations>::kCount,
- GemmConfig_::OutputTile::kW>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, ShapeCount<typename GemmConfig_::Warps>::kCount, GemmConfig_::kWarpSize>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerStgD>
- GlobalStoreTileTraits;
-
- /// The iterator to store D.
- typedef WmmaGemmGlobalIteratorCd<GlobalStoreTileTraits, Index_> GlobalStoreIteratorD;
- /// The transformer for D.
- typedef Copy<typename GlobalStoreIteratorD::Fragment> GlobalTransformerD;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
-
-#endif // defined CUTLASS_USE_WMMA_API
diff --git a/cutlass-example/cutlass/gemm/wmma_gemm_global_tile.h b/cutlass-example/cutlass/gemm/wmma_gemm_global_tile.h
deleted file mode 100644
index dbd57f6..0000000
--- a/cutlass-example/cutlass/gemm/wmma_gemm_global_tile.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines tile iterator traits for loading thread block-level tile from global memory.
-*/
-#pragma once
-
-#include <cutlass/gemm/gemm_global_tile.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, typename Tile_, typename Threads_, int kAccessSize_>
-struct WmmaGemmGlobalIteratorCdTraits : public GemmGlobalTileTraits<GemmOperand::kC,
- MatrixLayout::kColumnMajor,
- Scalar_,
- Tile_,
- Threads_,
- kAccessSize_> {
- /// The base class.
- typedef GemmGlobalTileTraits<GemmOperand::kC,
- MatrixLayout::kColumnMajor,
- Scalar_,
- Tile_,
- Threads_,
- kAccessSize_>
- Base;
-
- /// Override the strides in each dimension between different loads/stores.
- typedef Shape<0, 0, Base::Delta::kW, Base::Delta::kC> Delta;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- int thread_offset_h = threadIdx.x / Base::Threads::kW;
- int thread_offset_w = threadIdx.x % Base::Threads::kW * Base::ThreadsDelta::kW;
-
- return make_Coord(0, thread_offset_h, thread_offset_w, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename TileTraits_, typename Index_ = int>
-struct WmmaGemmGlobalIteratorCd : public TileIteratorBase<TileTraits_,
- typename TileTraits_::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kGlobal,
- Index_> {
- /// This class.
- typedef WmmaGemmGlobalIteratorCd<TileTraits_, Index_> This_;
- /// The traits.
- typedef TileTraits_ Traits;
- /// The base class.
- typedef TileIteratorBase<Traits,
- typename TileTraits_::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kGlobal,
- Index_>
- Base;
- /// Override the strides in each dimension between different loads/stores.
- typedef Shape<0, 0, Base::Delta::kW, Base::Delta::kC> ImmediateOffsetStrides;
- /// The layout.
- static MatrixLayout::Kind const kLayout = TileTraits_::kLayout;
-
- /// The scalar.
- typedef typename TileTraits_::Scalar Scalar;
- /// The pointer.
- typedef typename TileTraits_::Pointer Pointer;
- /// The threads.
- typedef typename TileTraits_::Threads Threads;
- /// The index.
- typedef Index_ Index;
- /// The thread offset functor.
- typedef typename TileTraits_::ThreadOffset ThreadOffset;
-
- /// The params.
- struct Params {
- /// The pointer.
- Pointer pointer;
- /// The stride in the H dimension to setup the thread in the block.
- Index stride_h;
- /// The strides to increment the pointer.
- Index inc_h, inc_advance;
- /// The column offset to compute the predicate for the columns.
- Index predicate_offset;
- /// The strides to increment the predicate offset.
- Index predicate_inc_h, predicate_inc_advance;
-
- /// Setup the params.
- CUTLASS_HOST_DEVICE int initialize(
- Pointer pointer, Index ld, Index n, Index epilogue_stride_w, Index epilogue_delta_w) {
- // The pointer.
- this->pointer = pointer;
- // Setup the base stride. One "group of threads" per column.
- stride_h = ld;
- // Each thread output 1 column per iteration. .
- inc_h = ld * TileTraits_::Threads::kH;
- inc_advance = inc_h + epilogue_stride_w;
-
- predicate_offset = n;
- predicate_inc_h = TileTraits_::Threads::kH;
- predicate_inc_advance = predicate_inc_h + epilogue_delta_w;
-
- // It worked.
- return 0;
- }
- };
-
- Params params;
-
- Coord<4> thread_offset;
-
- /// Ctor.
- CUTLASS_DEVICE WmmaGemmGlobalIteratorCd() {}
-
- /// Ctor.
- CUTLASS_DEVICE WmmaGemmGlobalIteratorCd(Params const& params,
- const Coord<3>& bounds,
- const Coord<3>& block,
- int const pointer_offset = 0,
- int const pred_offset = 0,
- ThreadOffset thread_offset_func = ThreadOffset())
-
- : params(params) {
- thread_offset = thread_offset_func();
- // Each warp works on a different column of the tile.
- int const h = thread_offset[1] + block[1];
- // Each lane writes a different element.
- int const w = thread_offset[2] + block[2];
- // Setup the pointer.
- this->params.pointer += ((h * params.stride_h + w) + pointer_offset);
-
- // Prepare the vector of predicates.
- for (int i = 0; i < Base::Iterations::kW; ++i) {
- predicates.set(i, w + i * Base::Delta::kW < bounds[2]);
- }
- this->params.predicate_offset -= (h + pred_offset);
- }
-
- /// The accessor.
- CUTLASS_DEVICE void get(typename Base::AccessType& value, int d, int h, int w, int c) const {
- int const imm =
- ComputeOffsetFromStrides<typename Base::ImmediateOffsetStrides>::get(0, 0, w, c);
- Load<Scalar, TileTraits_::kAccessSize, MemorySpace::kGlobal>::load(value, params.pointer, imm);
- }
-
- /// Increment the pointer in the C dimension.
- CUTLASS_DEVICE void inc_c() {}
- /// Increment the pointer in the W dimension.
- CUTLASS_DEVICE void inc_w() {}
- /// Increment the pointer in the H dimension.
- CUTLASS_DEVICE void inc_h() {
- params.pointer += params.inc_h;
- params.predicate_offset -= params.predicate_inc_h;
- }
- /// Increment the pointer in the D dimension.
- CUTLASS_DEVICE void inc_d() {}
- /// Increment the pointer to move to the next iteration.
- CUTLASS_DEVICE void inc_advance() {
- params.pointer += params.inc_advance;
- params.predicate_offset -= params.predicate_inc_advance;
- }
-
- /// The accessor.
- CUTLASS_DEVICE void set(typename Base::AccessType const& value, int d, int h, int w, int c) {
- int const imm =
- ComputeOffsetFromStrides<typename Base::ImmediateOffsetStrides>::get(d, h, w, 0);
- Store<Scalar, TileTraits_::kAccessSize, MemorySpace::kGlobal>::store(
- value, params.pointer, imm);
- }
-
- /// Test the predicate.
- CUTLASS_DEVICE bool valid(int d, int h, int w, int c) const {
- return predicates.at(w) && params.predicate_offset > 0;
- }
-
- /// The predicates for the row.
- cutlass::PredicateVector<Base::Iterations::kW> predicates;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/gemm/wmma_gemm_multiply_add.h b/cutlass-example/cutlass/gemm/wmma_gemm_multiply_add.h
deleted file mode 100644
index 5968350..0000000
--- a/cutlass-example/cutlass/gemm/wmma_gemm_multiply_add.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Implements warp-level matrix multiply-accumulate operation using CUDA WMMA API.
-*/
-#pragma once
-
-#include <cutlass/wmma_matrix.h>
-#ifdef CUTLASS_USE_WMMA_API
-#include <cutlass/fragment.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <MatrixLayout::Kind kLayoutA_,
- typename ScalarA_,
- MatrixLayout::Kind kLayoutB_,
- typename ScalarB_,
- MatrixLayout::Kind kLayoutC_,
- typename ScalarC_,
- typename AccumulatorsPerWarp_,
- typename InstructionShape_>
-struct WmmaGemmMultiplyAdd {
- /// The shape of the instruction.
- typedef InstructionShape_ InstructionShape;
- /// The number of threads per warp. That's a dummy configuration.
- typedef Shape<1, InstructionShape_::kH, InstructionShape_::kW> ThreadsPerWarp;
- /// The dimensions.
- typedef AccumulatorsPerWarp_ AccumulatorsPerWarp;
- /// The type for A.
- typedef ScalarA_ ScalarA;
- /// The type for B.
- typedef ScalarB_ ScalarB;
- /// The type for C and D.
- typedef ScalarC_ ScalarC;
- /// The number of iterations.
- typedef typename ShapeDiv<AccumulatorsPerWarp, InstructionShape>::Shape Iterations;
-
- /// The element for A.
- typedef WmmaMatrix<GemmOperand::kA, kLayoutA_, ScalarA, InstructionShape> ElementA;
- /// The fragment for A.
- typedef Fragment<ElementA, Iterations::kW> FragmentA;
-
- /// The element for B.
- typedef WmmaMatrix<GemmOperand::kB, kLayoutB_, ScalarB, InstructionShape> ElementB;
- /// The fragment for B.
- typedef Fragment<ElementB, Iterations::kH> FragmentB;
-
- /// The element for C.
- typedef WmmaMatrix<GemmOperand::kC, kLayoutC_, ScalarC, InstructionShape> ElementC;
- /// The fragment for C.
- typedef Fragment<ElementC, Iterations::kH * Iterations::kW> Accumulators;
-
- /// Ctor.
- CUTLASS_DEVICE WmmaGemmMultiplyAdd() {}
-
- /// Multiply : d = a*b.
- CUTLASS_DEVICE void multiply_add(FragmentA const& a,
- FragmentB const& b,
- Accumulators const& c,
- Accumulators& d) {
- for (int j = 0; j < Iterations::kH; ++j) {
- for (int i = 0; i < Iterations::kW; ++i) {
- // The input elements.
- ElementA const& elt_a = a[i];
- ElementB const& elt_b = b[j];
- ElementC const& elt_c = c[j * Iterations::kW + i];
-
- // The output element.
- ElementC& elt_d = d[j * Iterations::kW + i];
-
- // The wmma instruction.
- nvcuda::wmma::mma_sync(elt_d, elt_a, elt_b, elt_c);
- }
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
-
-#endif // defined CUTLASS_USE_WMMA_API
diff --git a/cutlass-example/cutlass/gemm/wmma_gemm_shared_tile.h b/cutlass-example/cutlass/gemm/wmma_gemm_shared_tile.h
deleted file mode 100644
index 7d15b26..0000000
--- a/cutlass-example/cutlass/gemm/wmma_gemm_shared_tile.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines iterator traits for efficiently loading and storing fragment to and from shared
- memory, specialized for WMMA GEMM.
-*/
-#pragma once
-
-#include <cutlass/wmma_matrix.h>
-#ifdef CUTLASS_USE_WMMA_API
-
-#include <cutlass/gemm/gemm_operand.h>
-#include <cutlass/reshape_tile.h>
-
-namespace cutlass {
-namespace gemm {
-
-template <class>
-struct Debug {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename Tile_,
- typename Warps_,
- int kWarpStride_,
- typename Iterations_,
- typename Delta_,
- typename WmmaShape_>
-struct WmmaGemmSharedLoadTileATraits {
- /// The operand.
- static GemmOperand::Kind const kOperand = GemmOperand::kA;
- /// The layout.
- static MatrixLayout::Kind const kLayout = kLayout_;
- /// The scalar.
- typedef Scalar_ Scalar;
- /// The pointer.
- typedef Scalar const* Pointer;
- /// The access size
- static int const kAccessSize = 1;
- /// The tile with skew.
- typedef Tile_ Tile;
- /// The number of warps.
- typedef Warps_ Warps;
- /// The warps strides.
- static int const kWarpStride = kWarpStride_;
- /// The number of iterations.
- typedef Iterations_ Iterations;
- /// The strides between iterations.
- typedef Delta_ Delta;
- /// The strides between iterations.
- typedef Delta_ ImmediateOffsetStrides;
- /// The shape of the WMMA instruction.
- typedef WmmaShape_ WmmaShape;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
- /// ThreadOffset
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- // The warp id.
- int const warp = threadIdx.x / kWarpSize;
- // The offset.
- int const offset = warp % Warps::kW * kWarpStride;
- return make_Coord(0, 0, offset, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename Tile_,
- typename Warps_,
- int kWarpStride_,
- typename Iterations_,
- typename Delta_,
- typename WmmaShape_>
-struct WmmaGemmSharedLoadTileBTraits {
- /// The operand.
- static GemmOperand::Kind const kOperand = GemmOperand::kB;
- /// The layout.
- static MatrixLayout::Kind const kLayout = kLayout_;
- /// The scalar.
- typedef Scalar_ Scalar;
- /// The pointer.
- typedef Scalar const* Pointer;
- /// The access size
- static int const kAccessSize = 1;
- /// The tile with skew.
- typedef Tile_ Tile;
- /// The number of warps.
- typedef Warps_ Warps;
- /// The warps strides.
- static int const kWarpStride = kWarpStride_;
- /// The number of iterations.
- typedef Iterations_ Iterations;
- /// The strides between iterations.
- typedef Delta_ Delta;
- /// The strides between iterations.
- typedef Delta_ ImmediateOffsetStrides;
- /// The shape of the WMMA instruction.
- typedef WmmaShape_ WmmaShape;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
- /// ThreadOffset
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- // The warp id.
- int const warp = threadIdx.x / kWarpSize;
- // The offset.
- int const offset = warp / Warps::kW * kWarpStride;
- return make_Coord(0, 0, offset, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename OutputTile_,
- typename Warps_,
- typename WmmaShape_,
- int kSkew_ = 0>
-struct WmmaGemmSharedStoreTileDTraits {
- /// The operand.
- static GemmOperand::Kind const kOperand = GemmOperand::kC;
- /// The layout.
- static MatrixLayout::Kind const kLayout = kLayout_;
- /// The scalar.
- typedef Scalar_ Scalar;
- // The access size
- static int const kAccessSize = 1;
- /// The pointer.
- typedef Scalar* Pointer;
- /// The number of warps.
- typedef Warps_ Warps;
- /// The shape of the WMMA instruction.
- typedef WmmaShape_ WmmaShape;
- /// The skew.
- static int const kSkew = kSkew_;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
- /// The tile with skew.
- typedef Shape<1, Warps_::kH * WmmaShape_::kH, OutputTile_::kW + kSkew_> Tile;
- /// The number of iterations needed to store the tile.
- typedef Shape<1, 1, OutputTile_::kW / Warps::kW / WmmaShape_::kW> Iterations;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, 0, Warps::kW * WmmaShape_::kW, 0> Delta;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, 0, Warps::kW * WmmaShape_::kW, 0> ImmediateOffsetStrides;
-
- /// ThreadOffset
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- // The warp id.
- int const warp = threadIdx.x / kWarpSize;
- // The starting column.
- int const h = warp / Warps::kW * WmmaShape::kH;
- // The w.
- int const w = warp % Warps::kW * WmmaShape::kW;
- // The offset.
- int const offset = h * Tile::kW + w;
- return make_Coord(0, 0, offset, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, typename Tile_, typename Threads_, int kScalarsPerLds_>
-struct WmmaGemmSharedLoadTileDTraits {
- /// The scalar.
- typedef Scalar_ Scalar;
- /// The pointer.
- typedef Scalar const* Pointer;
- /// The access size
- static int const kAccessSize = kScalarsPerLds_;
- /// The tile.
- typedef typename ReshapeTile<Tile_, kScalarsPerLds_>::Tile Tile;
- /// The threads.
- typedef typename ReshapeThreads<Tile, Threads_>::Threads Threads;
- /// The threads strides.
- typedef Shape<1, Tile::kW * Tile::kC, Tile::kC> ThreadsStrides;
- /// The memory space.
- static MemorySpace::Kind const kMemorySpace = MemorySpace::kShared;
-
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, Threads::kH * ShapeCount<Tile>::kWc, Threads::kW * kScalarsPerLds_> Delta;
- /// The strides in each dimension between different loads/stores.
- typedef Shape<0, Threads::kH * ShapeCount<Tile>::kWc, Threads::kW * kScalarsPerLds_>
- ImmediateOffsetStrides;
- /// The number of iterations needed to load/store the tile.
- typedef Shape<1, Tile::kH / Threads::kH, Tile::kW / Threads::kW, Tile::kC / kScalarsPerLds_>
- Iterations;
-
- /// ThreadOffset
- struct ThreadOffset {
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- // The offset.
- int const offset = ComputeThreadOffsetFromStrides<Threads, ThreadsStrides>::get();
- return make_Coord(0, 0, offset, 0);
- }
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
-
-#endif // defined CUTLASS_USE_WMMA_API
diff --git a/cutlass-example/cutlass/gemm/wmma_gemm_traits.h b/cutlass-example/cutlass/gemm/wmma_gemm_traits.h
deleted file mode 100644
index 7901201..0000000
--- a/cutlass-example/cutlass/gemm/wmma_gemm_traits.h
+++ /dev/null
@@ -1,574 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defies structural properties of GEMM targeting WMMA API in CUDA.
-*/
-#pragma once
-
-#include <cutlass/wmma_matrix.h>
-#ifdef CUTLASS_USE_WMMA_API
-
-#include <cutlass/convert.h>
-#include <cutlass/gemm/gemm.h>
-#include <cutlass/gemm/gemm_epilogue.h>
-#include <cutlass/gemm/gemm_epilogue_traits.h>
-#include <cutlass/gemm/gemm_global_tile.h>
-#include <cutlass/gemm/gemm_shared_tile.h>
-#include <cutlass/gemm/gemm_traits.h>
-#include <cutlass/gemm/wmma_gemm_epilogue_traits.h>
-#include <cutlass/gemm/wmma_gemm_global_tile.h>
-#include <cutlass/gemm/wmma_gemm_multiply_add.h>
-
-namespace cutlass {
-namespace gemm {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The tile size for the GEMM KxNxM.
- typename OutputTile_,
- /// The output type.
- typename ScalarC_,
- /// The accumulator type.
- typename Accumulator_,
- /// The number of accumulators per warp.
- typename AccumulatorsPerWarp_,
- /// The shape of the WMMA instruction.
- typename InstructionShape_,
- /// The number of scalars per LDG for A.
- int kScalarsPerLdgA_,
- /// The number of scalars per LDG for B.
- int kScalarsPerLdgB_>
-struct WmmaGemmConfig : public GemmConfig<
- /// The scalar type for A.
- half,
- /// The scalar type for B.
- half,
- /// The scalar type for C.
- ScalarC_,
- /// The scalar type for D.
- ScalarC_,
- /// The tile size for the GEMM KxNxM.
- OutputTile_,
- /// The functor to do the math in the main loop.
- WmmaGemmMultiplyAdd<kLayoutA_,
- half,
- kLayoutB_,
- half,
- MatrixLayout::kColumnMajor,
- Accumulator_,
- AccumulatorsPerWarp_,
- InstructionShape_>,
- /// The number of scalars per LDG for A.
- kScalarsPerLdgA_,
- /// The number of scalars per STS for A.
- kScalarsPerLdgA_,
- /// The number of scalars per LDS for A.
- 8,
- /// The number of scalars per LDG for B.
- kScalarsPerLdgB_,
- /// The number of scalars per STS for B.
- kScalarsPerLdgB_,
- /// The number of scalars per LDS for B.
- 8,
- /// The number of scalars per LDG for C and STG for D.
- 16 / sizeof(ScalarC_),
- /// The number of scalars per STS for D.
- 16 / sizeof(ScalarC_),
- /// The number of scalars per LDS for D.
- 16 / sizeof(ScalarC_),
- /// The number of stages in shared memory.
- 1> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename GemmConfig_>
-struct WmmaGemmTileTraitsHelperA {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct WmmaGemmTileTraitsHelperA<MatrixLayout::kColumnMajor, GemmConfig_>
- : public GemmTileTraitsHelperA<MatrixLayout::kColumnMajor, GemmConfig_> {
- /// The base config.
- typedef GemmTileTraitsHelperA<MatrixLayout::kColumnMajor, GemmConfig_> Base;
-
- /// The skew.
- static int const kSkew = 16 / sizeof(typename Base::MultiplyAddScalar);
- /// The shared tile size.
- typedef Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kD,
- GemmConfig_::OutputTile::kW + kSkew>
- Tile;
-
- /// WMMA matrix
- typedef WmmaMatrix<GemmOperand::kA,
- MatrixLayout::kColumnMajor,
- typename Base::MultiplyAddScalar,
- typename GemmConfig_::InstructionShape>
- WmmaMatrix;
-
- /// The traits class to build the iterator to store data to shared memory for A^N.
- typedef GemmSharedStoreTileAbTraits<
- // The pointer.
- typename Base::MultiplyAddScalar,
- // The tile has size KxM in GEMM's terminology.
- Tile,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- typename Base::GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- GemmConfig_::kScalarsPerStsA>
- SharedStoreTileTraits;
-
- /// The number of elements loaded in one LDG.
- static int const kScalarsPerW = GemmConfig_::InstructionShape::kW * GemmConfig_::Warps::kW;
- /// The number of scalars loaded per iteration.
- static int const kScalarsPerIteration = Tile::kW * GemmConfig_::InstructionShape::kD;
- /// The traits class to build the iterator to load from shared memory for A.
- typedef WmmaGemmSharedLoadTileATraits<
- // The layout of the matrix.
- MatrixLayout::kColumnMajor,
- // The pointer.
- typename Base::MultiplyAddScalar,
- // The output tile size.
- Tile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The strides between warps.
- GemmConfig_::InstructionShape::kW,
- // The number of iterations to load the data.
- Shape<1, 1, GemmConfig_::OutputTile::kW / kScalarsPerW>,
- // The stride between iterations.
- Shape<kScalarsPerIteration, 0, kScalarsPerW, 0>,
- // The shape of the instruction.
- typename GemmConfig_::InstructionShape>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct WmmaGemmTileTraitsHelperA<MatrixLayout::kRowMajor, GemmConfig_> {
- /// The layout.
- static MatrixLayout::Kind const kLayout = MatrixLayout::kRowMajor;
-
- /// The input scalar.
- typedef typename GemmConfig_::ScalarA Scalar;
- /// The scalar stored in shared memory.
- typedef typename GemmConfig_::MultiplyAdd::ScalarA MultiplyAddScalar;
-
- /// WMMA matrix
- typedef WmmaMatrix<GemmOperand::kA,
- MatrixLayout::kRowMajor,
- MultiplyAddScalar,
- typename GemmConfig_::InstructionShape>
- WmmaMatrix;
-
- /// The traits class to build the iterator to load data from global memory for A^T.
- typedef GemmGlobalTileTraits<
- // That's A.
- GemmOperand::kA,
- // A is row-major.
- MatrixLayout::kRowMajor,
- // The pointer is float const.
- Scalar const,
- // The tile has size KxM in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kW, GemmConfig_::OutputTile::kD>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, GemmConfig_::kThreads / GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kD>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgA>
- GlobalTileTraits;
-
- /// The skew.
- static int const kSkew = 16 / sizeof(MultiplyAddScalar);
- /// The tile.
- typedef Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kW,
- GemmConfig_::OutputTile::kD + kSkew>
- Tile;
-
- /// The traits class to build the iterator to store data to shared memory for A^N.
- typedef GemmSharedStoreTileAbTraits<
- // The pointer.
- MultiplyAddScalar,
- // The tile has size KxM in GEMM's terminology.
- Tile,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- GemmConfig_::kScalarsPerStsA>
- SharedStoreTileTraits;
-
- /// The number of elements loaded in one LDG.
- static int const kScalarsPerW = GemmConfig_::InstructionShape::kW * GemmConfig_::Warps::kW;
- /// The traits class to build the iterator to load from shared memory for A.
- typedef WmmaGemmSharedLoadTileATraits<
- // The layout of the matrix.
- MatrixLayout::kRowMajor,
- // The pointer.
- MultiplyAddScalar,
- // The tile in shared memory.
- Tile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The strides between warps.
- GemmConfig_::InstructionShape::kW * Tile::kW,
- // The number of iterations to load the data.
- Shape<1, 1, GemmConfig_::OutputTile::kW / kScalarsPerW>,
- // The stride between iterations.
- Shape<GemmConfig_::InstructionShape::kD, 0, kScalarsPerW * Tile::kW>,
- // The shape of the instruction.
- typename GemmConfig_::InstructionShape>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <enum MatrixLayout::Kind kLayout_, typename GemmConfig_>
-struct WmmaGemmTileTraitsHelperB {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct WmmaGemmTileTraitsHelperB<MatrixLayout::kRowMajor, GemmConfig_>
- : public GemmTileTraitsHelperB<MatrixLayout::kRowMajor, GemmConfig_> {
- /// The base config.
- typedef GemmTileTraitsHelperB<MatrixLayout::kRowMajor, GemmConfig_> Base;
-
- /// The skew.
- static int const kSkew = 16 / sizeof(typename Base::MultiplyAddScalar);
- /// The shared tile size.
- typedef Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kD,
- GemmConfig_::OutputTile::kH + kSkew>
- Tile;
-
- /// WMMA matrix
- typedef WmmaMatrix<GemmOperand::kB,
- MatrixLayout::kRowMajor,
- typename Base::MultiplyAddScalar,
- typename GemmConfig_::InstructionShape>
- WmmaMatrix;
-
- /// The traits class to build the iterator to store data to shared memory for B^T.
- typedef GemmSharedStoreTileAbTraits<
- // The pointer.
- typename Base::MultiplyAddScalar,
- // The tile has size KxM in GEMM's terminology.
- Tile,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- typename Base::GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- GemmConfig_::kScalarsPerStsB>
- SharedStoreTileTraits;
-
- /// The number of elements loaded in one LDG.
- static int const kScalarsPerW = GemmConfig_::InstructionShape::kH * GemmConfig_::Warps::kH;
- /// The number of scalars loaded per iteration.
- static int const kScalarsPerIteration = Tile::kW * GemmConfig_::InstructionShape::kD;
- /// The traits class to build the iterator to load from shared memory for B.
- typedef WmmaGemmSharedLoadTileBTraits<
- // The layout of the matrix.
- MatrixLayout::kRowMajor,
- // The pointer.
- typename Base::MultiplyAddScalar,
- // The output tile size.
- Tile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The strides between warps.
- GemmConfig_::InstructionShape::kH,
- // The number of iterations to load the data.
- Shape<1, 1, GemmConfig_::OutputTile::kH / kScalarsPerW>,
- // The stride between iterations.
- Shape<kScalarsPerIteration, 0, kScalarsPerW, 0>,
- // The shape of the instruction.
- typename GemmConfig_::InstructionShape>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmConfig_>
-struct WmmaGemmTileTraitsHelperB<MatrixLayout::kColumnMajor, GemmConfig_> {
- /// The layout.
- static MatrixLayout::Kind const kLayout = MatrixLayout::kColumnMajor;
-
- /// The input scalar.
- typedef typename GemmConfig_::ScalarB Scalar;
- /// The scalar stored in shared memory.
- typedef typename GemmConfig_::MultiplyAdd::ScalarB MultiplyAddScalar;
-
- /// WMMA matrix
- typedef WmmaMatrix<GemmOperand::kB,
- MatrixLayout::kColumnMajor,
- MultiplyAddScalar,
- typename GemmConfig_::InstructionShape>
- WmmaMatrix;
-
- /// The traits class to build the iterator to load data from global memory for B^N.
- typedef GemmGlobalTileTraits<
- // That's B.
- GemmOperand::kB,
- // A is row-major.
- MatrixLayout::kColumnMajor,
- // The pointer is float const.
- Scalar const,
- // The tile has size KxM in GEMM's terminology.
- Shape<1, GemmConfig_::OutputTile::kH, GemmConfig_::OutputTile::kD>,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- Shape<1, GemmConfig_::kThreads / GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kD>,
- // The number of scalars per LDG (LDG.32 or LDG.128, etc).
- GemmConfig_::kScalarsPerLdgB>
- GlobalTileTraits;
-
- /// The skew.
- static int const kSkew = 16 / sizeof(MultiplyAddScalar);
- /// The tile.
- typedef Shape<GemmConfig_::kStages,
- GemmConfig_::OutputTile::kH,
- GemmConfig_::OutputTile::kD + kSkew>
- Tile;
-
- /// The traits class to build the iterator to store data to shared memory for B^N.
- typedef GemmSharedStoreTileAbTraits<
- // The pointer.
- MultiplyAddScalar,
- // The tile has size KxM in GEMM's terminology.
- Tile,
- // The threads are distributed as warps x 32 (the traits may reorganize).
- typename GlobalTileTraits::Threads,
- // The number of scalars per STS (STS.32 or STS.128, etc).
- GemmConfig_::kScalarsPerStsB>
- SharedStoreTileTraits;
-
- /// The number of elements loaded in one LDG.
- static int const kScalarsPerW = GemmConfig_::InstructionShape::kH * GemmConfig_::Warps::kH;
- /// The traits class to build the iterator to load from shared memory for B.
- typedef WmmaGemmSharedLoadTileBTraits<
- // The layout of the matrix.
- MatrixLayout::kColumnMajor,
- // The pointer.
- MultiplyAddScalar,
- // The tile in shared memory.
- Tile,
- // The number of warps.
- typename GemmConfig_::Warps,
- // The strides between warps.
- GemmConfig_::InstructionShape::kH * Tile::kW,
- // The number of iterations to load the data.
- Shape<1, 1, GemmConfig_::OutputTile::kH / kScalarsPerW>,
- // The stride between iterations.
- Shape<GemmConfig_::InstructionShape::kD, 0, kScalarsPerW * Tile::kW>,
- // The shape of the instruction.
- typename GemmConfig_::InstructionShape>
- SharedLoadTileTraits;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The output tile.
- typename OutputTile_,
- /// The output type.
- typename ScalarC_,
- /// The accumulator type.
- typename Accumulator_,
- /// The functor to do the math in the epilogue.
- typename EpilogueFunctor_,
- /// The number of accumulators per warp.
- typename AccumulatorsPerWarp_,
- /// The shape of the WMMA instruction.
- typename InstructionShape_,
- /// The number of halfs loaded in one LDG for A.
- int kScalarsPerLdgA_,
- /// The number of halfs loaded in one LDG for B.
- int kScalarsPerLdgB_,
- /// The index.
- typename Index_>
-struct WmmaGemmTraitsHelper {
- /// The WMMA GEMM config.
- typedef WmmaGemmConfig<kLayoutA_,
- kLayoutB_,
- OutputTile_,
- ScalarC_,
- Accumulator_,
- AccumulatorsPerWarp_,
- InstructionShape_,
- kScalarsPerLdgA_,
- kScalarsPerLdgB_>
- GemmConfig;
-
- /// The GEMM config for A.
- typedef WmmaGemmTileTraitsHelperA<kLayoutA_, GemmConfig> GemmTileTraitsHelperA;
- /// The GEMM config for B.
- typedef WmmaGemmTileTraitsHelperB<kLayoutB_, GemmConfig> GemmTileTraitsHelperB;
-
- /// The iterator to load A from global memory.
- typedef GemmGlobalIteratorAb<typename GemmTileTraitsHelperA::GlobalTileTraits, Index_>
- GlobalLoadIteratorA;
- /// The default transformer for A.
- typedef Copy<typename GlobalLoadIteratorA::Fragment> GlobalTransformerA;
- /// The iterator to store A to shared memory.
- typedef TileStoreIterator<typename GemmTileTraitsHelperA::SharedStoreTileTraits,
- typename GemmTileTraitsHelperA::SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorA;
- /// The stream to load A from global memory to shared memory.
- typedef GlobalLoadStream<GlobalLoadIteratorA, SharedStoreIteratorA, GlobalTransformerA>
- GlobalLoadStreamA;
-
- /// The iterator to load B from global memory.
- typedef GemmGlobalIteratorAb<typename GemmTileTraitsHelperB::GlobalTileTraits, Index_>
- GlobalLoadIteratorB;
- // The default transformer for B.
- typedef Copy<typename GlobalLoadIteratorB::Fragment> GlobalTransformerB;
- /// The iterator to store B to shared memory.
- typedef TileStoreIterator<typename GemmTileTraitsHelperB::SharedStoreTileTraits,
- typename GemmTileTraitsHelperB::SharedStoreTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared>
- SharedStoreIteratorB;
- /// The stream to load B from global memory to shared memory.
- typedef GlobalLoadStream<GlobalLoadIteratorB, SharedStoreIteratorB, GlobalTransformerB>
- GlobalLoadStreamB;
-
- /// The iterator to load A from shared memory.
- typedef TileLoadIterator<typename GemmTileTraitsHelperA::SharedLoadTileTraits,
- typename GemmTileTraitsHelperA::SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared,
- Index_,
- typename GemmTileTraitsHelperA::WmmaMatrix,
- IteratorFragment::kWmmaMatrix>
- SharedLoadIteratorA;
- /// The stream to load A from shared memory.
- typedef SharedLoadStream<SharedLoadIteratorA> SharedLoadStreamA;
- /// The iterator to load B from shared memory.
- typedef TileLoadIterator<typename GemmTileTraitsHelperB::SharedLoadTileTraits,
- typename GemmTileTraitsHelperB::SharedLoadTileTraits::Scalar,
- IteratorAdvance::kH,
- MemorySpace::kShared,
- Index_,
- typename GemmTileTraitsHelperB::WmmaMatrix,
- IteratorFragment::kWmmaMatrix>
- SharedLoadIteratorB;
- /// The stream to load B from shared memory.
- typedef SharedLoadStream<SharedLoadIteratorB> SharedLoadStreamB;
-
- /// The functor to do the multiply-add in the main loop.
- typedef typename GemmConfig::MultiplyAdd MultiplyAdd;
- /// The object to clear accumulators.
- typedef ClearAccumulators<typename MultiplyAdd::ScalarC> ClearAccumulators;
-
- /// The helper to create the epilogue traits.
- typedef WmmaGemmEpilogueTraitsHelper<GemmConfig, EpilogueFunctor_, Index_> EpilogueTraitsHelper;
- /// The traits class for the epilogue.
- typedef SimplifiedGemmEpilogueTraits<GemmConfig, EpilogueFunctor_, Index_, EpilogueTraitsHelper>
- GemmEpilogueTraits;
- /// The epilogue.
- typedef GemmEpilogue<GemmEpilogueTraits> Epilogue;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename OutputTile_, typename DefaultShape_ = Shape<64, 32, 64> >
-struct WmmaGemmAccumulatorsPerWarp {
- typedef typename ShapeMin<OutputTile_, DefaultShape_>::Shape Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <
- /// The layout for A.
- MatrixLayout::Kind kLayoutA_,
- /// The layout for B.
- MatrixLayout::Kind kLayoutB_,
- /// The tile size for the GEMM KxNxM.
- typename OutputTile_ = Shape<64, 128, 128>,
- /// The output type.
- typename ScalarC_ = float,
- /// The functor to do the math in the epilogue.
- typename EpilogueFunctor_ = LinearScaling<ScalarC_>,
- /// The accumulator type.
- typename Accumulator_ = ScalarC_,
- /// The number of accumulators per warp.
- typename AccumulatorsPerWarp_ = typename WmmaGemmAccumulatorsPerWarp<OutputTile_>::Shape,
- /// The shape of the WMMA instruction.
- typename InstructionShape_ = Shape<16, 16, 16>,
- /// The number of scalars per LDG for A.
- int kScalarsPerLdgA_ = 8,
- /// The number of scalars per LDG for B.
- int kScalarsPerLdgB_ = 8,
- /// The index.
- typename Index_ = int,
- /// The helper class.
- typename Helper_ = WmmaGemmTraitsHelper<kLayoutA_,
- kLayoutB_,
- OutputTile_,
- ScalarC_,
- Accumulator_,
- EpilogueFunctor_,
- AccumulatorsPerWarp_,
- InstructionShape_,
- kScalarsPerLdgA_,
- kScalarsPerLdgB_,
- Index_> >
-struct WmmaGemmTraits : public GemmTraits<
- // The config.
- typename Helper_::GemmConfig,
- // The stream to load A from global memory to shared memory.
- typename Helper_::GlobalLoadStreamA,
- // The stream to load B from global memory to shared memory.
- typename Helper_::GlobalLoadStreamB,
- // The stream to load A from shared memory.
- typename Helper_::SharedLoadStreamA,
- // The stream to load B from shared memory.
- typename Helper_::SharedLoadStreamB,
- // The epilogue.
- typename Helper_::Epilogue,
- // The block swizzle to reorganize the grid.
- IdentityBlockSwizzle,
- // The index.
- Index_,
- // The tool used to clear accumulators.
- typename Helper_::ClearAccumulators> {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace gemm
-} // namespace cutlass
-
-#endif // defined CUTLASS_USE_WMMA_API
diff --git a/cutlass-example/cutlass/iterator_access.h b/cutlass-example/cutlass/iterator_access.h
deleted file mode 100644
index e94beb7..0000000
--- a/cutlass-example/cutlass/iterator_access.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Free functions for loading and storing to implementations of tile iteartor concepts.
-*/
-#pragma once
-
-#include <cutlass/fragment_load_store.h>
-#include <cutlass/load_store.h>
-#include <cutlass/predicate_vector.h>
-#include <cutlass/shape.h>
-
-namespace cutlass {
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Loads a fragment from an input iterator
-template <typename InputIterator, typename Fragment>
-CUTLASS_HOST_DEVICE void iterator_load(InputIterator &iterator, Fragment &fragment) {
- typename InputIterator::FragmentIterator frag_iterator(fragment);
- for (int d = 0; d < InputIterator::Iterations::kD; ++d) {
- for (int h = 0; h < InputIterator::Iterations::kH; ++h) {
- for (int w = 0; w < InputIterator::Iterations::kW; ++w) {
- for (int c = 0; c < InputIterator::Iterations::kC; ++c) {
- if (iterator.valid(d, h, w, c)) {
- iterator.get(reinterpret_cast<typename InputIterator::AccessType &>(
- frag_iterator.at(d, h, w, c)),
- d,
- h,
- w,
- c);
- }
- }
- if (w < InputIterator::Iterations::kW - 1) {
- iterator.inc_w();
- }
- }
- if (h < InputIterator::Iterations::kH - 1) {
- iterator.inc_h();
- }
- }
- if (d < InputIterator::Iterations::kD - 1) {
- iterator.inc_d();
- }
- }
- iterator.inc_advance();
-}
-
-/// Loads a fragment from a shared memory input iterator
-template <typename InputIterator, typename Fragment>
-CUTLASS_DEVICE void shared_iterator_load(InputIterator &iterator, Fragment &fragment) {
- typename InputIterator::FragmentIterator frag_iterator(fragment);
- for (int d = 0; d < InputIterator::Iterations::kD; ++d) {
- for (int h = 0; h < InputIterator::Iterations::kH; ++h) {
- for (int w = 0; w < InputIterator::Iterations::kW; ++w) {
- for (int c = 0; c < InputIterator::Iterations::kC; ++c) {
- int const offset =
- ComputeOffsetFromStrides<typename InputIterator::ImmediateOffsetStrides>::get(
- d, h, w, c);
-
- FragmentLoad<InputIterator::kIteratorFragment,
- InputIterator::Tile::kC,
- typename InputIterator::Scalar,
- InputIterator::kMemorySpace,
- typename InputIterator::FragmentElement,
- InputIterator::Tile::kW>::load(frag_iterator.at(d, h, w, c),
- iterator.data(),
- offset);
- }
- }
- }
- }
-}
-
-/// Loads a fragment from a shared memory input iterator
-template <typename InputIterator, typename Fragment>
-CUTLASS_DEVICE void shared_iterator_load(InputIterator &iterator, Fragment &fragment, int d) {
- typename InputIterator::FragmentIterator frag_iterator(fragment);
- for (int h = 0; h < InputIterator::Iterations::kH; ++h) {
- for (int w = 0; w < InputIterator::Iterations::kW; ++w) {
- for (int c = 0; c < InputIterator::Iterations::kC; ++c) {
- int const offset =
- ComputeOffsetFromStrides<typename InputIterator::ImmediateOffsetStrides>::get(
- d, h, w, c);
-
- FragmentLoad<InputIterator::kIteratorFragment,
- InputIterator::Tile::kC,
- typename InputIterator::Scalar,
- InputIterator::kMemorySpace,
- typename InputIterator::FragmentElement,
- InputIterator::Tile::kW>::load(frag_iterator.at(0, h, w, c),
- iterator.data(),
- offset);
- }
- }
- }
-}
-
-/// Loads a fragment from an input iterator, masked by a predicate iterator
-template <typename InputIterator, typename Fragment, typename ConstPredicateAdapter>
-CUTLASS_HOST_DEVICE void iterator_load_post_increment(InputIterator &iterator,
- Fragment &fragment,
- typename InputIterator::Index offset,
- ConstPredicateAdapter predicate_adapter) {
- for (int d = 0; d < InputIterator::Iterations::kD; ++d, iterator.inc_d()) {
- for (int h = 0; h < InputIterator::Iterations::kH; ++h, iterator.inc_h()) {
- for (int w = 0; w < InputIterator::Iterations::kW; ++w, iterator.inc_w()) {
- if (predicate_adapter.at(d, h, w, 0)) {
- int idx = InputIterator::Tile::kC *
- (w + InputIterator::Iterations::kW * (h + InputIterator::Iterations::kH * d));
-
- Load<typename Fragment::Element, InputIterator::Tile::kC, InputIterator::kMemorySpace>::
- load(reinterpret_cast<typename InputIterator::AccessType &>(fragment[idx]),
- iterator.data(),
- offset);
- }
- }
- }
- }
-}
-
-/// Loads a fragment from an input iterator
-template <typename InputIterator, typename Fragment>
-CUTLASS_HOST_DEVICE void iterator_load_post_increment(InputIterator &iterator,
- Fragment &fragment,
- typename InputIterator::Index offset = 0) {
- TrivialPredicateTileAdapter pred;
- iterator_load_post_increment(iterator, fragment, offset, pred);
-}
-
-/// Loads a fragment from an input iterator
-template <typename InputIterator, typename Fragment, typename ConstPredicateAdapter>
-CUTLASS_HOST_DEVICE void iterator_load_post_increment(InputIterator &iterator,
- Fragment &fragment,
- ConstPredicateAdapter pred_it) {
- iterator_load_post_increment(iterator, fragment, 0, pred_it);
-}
-
-template <typename InputIterator, typename Fragment, typename ConstPredicateAdapter>
-CUTLASS_HOST_DEVICE void iterator_load(InputIterator const &_iterator,
- Fragment &fragment,
- typename InputIterator::Index offset,
- ConstPredicateAdapter predicate_adapter) {
- InputIterator iterator(_iterator);
- iterator_load_post_increment(iterator, fragment, offset, predicate_adapter);
-}
-
-/// Loads a fragment from an input iterator
-template <typename InputIterator, typename Fragment>
-CUTLASS_HOST_DEVICE void iterator_load(InputIterator const &iterator,
- Fragment &fragment,
- typename InputIterator::Index offset = 0) {
- TrivialPredicateTileAdapter pred;
- iterator_load(iterator, fragment, offset, pred);
-}
-
-/// Loads a fragment from an input iterator
-template <typename InputIterator, typename Fragment, typename ConstPredicateAdapter>
-CUTLASS_HOST_DEVICE void iterator_load(InputIterator const &iterator,
- Fragment &fragment,
- ConstPredicateAdapter pred_it) {
- iterator_load(iterator, fragment, 0, pred_it);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Stores a fragment to an output iterator
-template <typename OutputIterator, typename Fragment>
-CUTLASS_HOST_DEVICE void iterator_store(OutputIterator &iterator, Fragment &fragment) {
- typename OutputIterator::FragmentIterator frag_iterator(fragment);
- for (int d = 0; d < OutputIterator::Iterations::kD; ++d) {
- for (int h = 0; h < OutputIterator::Iterations::kH; ++h) {
- for (int w = 0; w < OutputIterator::Iterations::kW; ++w) {
- if (iterator.valid(d, h, w, 0)) {
- iterator.set(reinterpret_cast<typename OutputIterator::AccessType const &>(
- frag_iterator.at(d, h, w, 0)),
- d,
- h,
- w,
- 0);
- }
- if (w < OutputIterator::Iterations::kW - 1) {
- iterator.inc_w();
- }
- }
- if (h < OutputIterator::Iterations::kH - 1) {
- iterator.inc_h();
- }
- }
- if (d < OutputIterator::Iterations::kD - 1) {
- iterator.inc_d();
- }
- }
- iterator.inc_advance();
-}
-
-/// Stores a fragment to a shared memory output iterator
-template <typename OutputIterator, typename Fragment>
-CUTLASS_DEVICE void shared_iterator_store(OutputIterator &iterator, Fragment const &fragment) {
- typename OutputIterator::FragmentConstIterator frag_iterator(fragment);
- for (int d = 0; d < OutputIterator::Iterations::kD; ++d) {
- for (int h = 0; h < OutputIterator::Iterations::kH; ++h) {
- for (int w = 0; w < OutputIterator::Iterations::kW; ++w) {
- for (int c = 0; c < OutputIterator::Iterations::kC; ++c) {
- int const offset =
- ComputeOffsetFromStrides<typename OutputIterator::ImmediateOffsetStrides>::get(
- d, h, w, c);
-
- FragmentStore<OutputIterator::kIteratorFragment,
- OutputIterator::Tile::kC,
- typename OutputIterator::Scalar,
- OutputIterator::kMemorySpace,
- typename OutputIterator::FragmentElement,
- OutputIterator::Tile::kW>::store(frag_iterator.at(d, h, w, c),
- iterator.data(),
- offset);
- }
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Stores a fragment to an output iterator, masked by a predicate iterator
-template <typename OutputIterator, typename Fragment, typename ConstPredicateAdapter>
-CUTLASS_HOST_DEVICE void iterator_store_post_increment(OutputIterator &iterator,
- Fragment const &fragment,
- typename OutputIterator::Index offset,
- ConstPredicateAdapter predicate_adapter) {
- for (int d = 0; d < OutputIterator::Iterations::kD; ++d, iterator.inc_d()) {
- for (int h = 0; h < OutputIterator::Iterations::kH; ++h, iterator.inc_h()) {
- for (int w = 0; w < OutputIterator::Iterations::kW; ++w, iterator.inc_w()) {
- if (predicate_adapter.at(d, h, w, 0)) {
- int idx = OutputIterator::Tile::kC *
- (w + OutputIterator::Iterations::kW * (h + OutputIterator::Iterations::kH * d));
-
- Store<typename Fragment::Element,
- OutputIterator::Tile::kC,
- OutputIterator::kMemorySpace>::
- store(reinterpret_cast<typename OutputIterator::AccessType const &>(fragment[idx]),
- iterator.data(),
- offset);
- }
- }
- }
- }
-}
-
-/// Stores a fragment to an output iterator
-template <typename OutputIterator, typename Fragment>
-CUTLASS_HOST_DEVICE void iterator_store_post_increment(OutputIterator &iterator,
- Fragment const &fragment,
- typename OutputIterator::Index offset = 0) {
- TrivialPredicateTileAdapter pred;
- iterator_store_post_increment(iterator, fragment, offset, pred);
-}
-
-/// Stores a fragment to an output iterator
-template <typename OutputIterator, typename Fragment, typename ConstPredicateAdapter>
-CUTLASS_HOST_DEVICE void iterator_store_post_increment(OutputIterator &iterator,
- Fragment const &fragment,
- ConstPredicateAdapter pred_it) {
- iterator_store_post_increment(iterator, fragment, 0, pred_it);
-}
-
-/// Stores a fragment to an output iterator, masked by a predicate iterator
-template <typename OutputIterator, typename Fragment, typename ConstPredicateAdapter>
-CUTLASS_HOST_DEVICE void iterator_store(OutputIterator const &_iterator,
- Fragment const &fragment,
- typename OutputIterator::Index offset,
- ConstPredicateAdapter predicate_adapter) {
- OutputIterator iterator(_iterator);
- iterator_store_post_increment(iterator, fragment, offset, predicate_adapter);
-}
-
-/// Stores a fragment to an output iterator
-template <typename OutputIterator, typename Fragment>
-CUTLASS_HOST_DEVICE void iterator_store(OutputIterator const &iterator,
- Fragment const &fragment,
- typename OutputIterator::Index offset = 0) {
- TrivialPredicateTileAdapter pred;
- iterator_store(iterator, fragment, offset, pred);
-}
-
-/// Stores a fragment to an output iterator
-template <typename OutputIterator, typename Fragment, typename ConstPredicateAdapter>
-CUTLASS_HOST_DEVICE void iterator_store(OutputIterator const &iterator,
- Fragment const &fragment,
- ConstPredicateAdapter pred_it) {
- iterator_store(iterator, fragment, 0, pred_it);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/load_store.h b/cutlass-example/cutlass/load_store.h
deleted file mode 100644
index 5cb5eb6..0000000
--- a/cutlass-example/cutlass/load_store.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines abstractions for efficiently loading and storing vectors to memory.
-*/
-#pragma once
-
-#include <cutlass/vector.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief Enum to specify which memory space data resides in.
-*/
-struct MemorySpace {
- enum Kind {
- kGeneric, // Data accessed through pointer dereferencing
- kShared, // Data resides in shared memory
- kGlobal // Data resides in global memory
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_,
- int Lanes_,
- MemorySpace::Kind Memory_,
- bool = (Lanes_ > 1),
- size_t = (sizeof(Scalar_) * Lanes_)>
-struct Load {
- /// The output type.
- typedef typename Vectorize<Scalar_, Lanes_>::Type AccessType;
-
- /// The load function.
- static CUTLASS_DEVICE void load(AccessType& dst, Scalar_ const* pointer, int offset) {
- dst = reinterpret_cast<AccessType const*>(&pointer[offset])[0];
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int Lanes_, MemorySpace::Kind Memory_>
-struct Load<Scalar_, Lanes_, Memory_, true, 4> {
- /// The output type.
- typedef typename Vectorize<Scalar_, Lanes_>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void load(AccessType& dst, Scalar_ const* pointer, int offset) {
- dst.registers[0] = reinterpret_cast<uint32_t const*>(&pointer[offset])[0];
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int Lanes_, MemorySpace::Kind Memory_>
-struct Load<Scalar_, Lanes_, Memory_, true, 8> {
- /// The output type.
- typedef typename Vectorize<Scalar_, Lanes_>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void load(AccessType& dst, Scalar_ const* pointer, int offset) {
- uint2 tmp = reinterpret_cast<uint2 const*>(&pointer[offset])[0];
- dst.registers[0] = tmp.x;
- dst.registers[1] = tmp.y;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <MemorySpace::Kind Memory_>
-struct Load<double, 2, Memory_, true, 16> {
- /// The output type.
- typedef typename Vectorize<double, 2>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void load(AccessType& dst, double const* pointer, int offset) {
- double2 tmp = reinterpret_cast<double2 const*>(&pointer[offset])[0];
- dst[0] = tmp.x;
- dst[1] = tmp.y;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__CUDACC_VERSION_MAJOR) && __CUDACC_VERSION_MAJOR < 10
-// WAR bug in NVCC where the upper and lower half of the register end up being the same
-template <MemorySpace::Kind Memory_>
-struct Load<half, 8, Memory_, true, 16> {
- /// The output type.
- typedef typename Vectorize<half, 8>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void load(AccessType& dst, half const* pointer, int offset) {
- int2 tmp = reinterpret_cast<int2 const*>(&pointer[offset])[0];
- dst.registers[0] = tmp.x;
- dst.registers[1] = tmp.y;
-
- tmp = reinterpret_cast<int2 const*>(&pointer[offset + 4])[0];
- dst.registers[2] = tmp.x;
- dst.registers[3] = tmp.y;
- }
-};
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int Lanes_, MemorySpace::Kind Memory_>
-struct Load<Scalar_, Lanes_, Memory_, true, 16> {
- /// The output type.
- typedef typename Vectorize<Scalar_, Lanes_>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void load(AccessType& dst, Scalar_ const* pointer, int offset) {
- uint4 tmp = reinterpret_cast<uint4 const*>(&pointer[offset])[0];
- dst.registers[0] = tmp.x;
- dst.registers[1] = tmp.y;
- dst.registers[2] = tmp.z;
- dst.registers[3] = tmp.w;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_,
- int Lanes_,
- MemorySpace::Kind Memory_,
- bool = (Lanes_ > 1),
- size_t = (sizeof(Scalar_) * Lanes_)>
-struct Store {
- /// The output type.
- typedef typename Vectorize<Scalar_, Lanes_>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void store(AccessType const& src, Scalar_* pointer, int offset) {
- pointer[offset] = src;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int Lanes_, MemorySpace::Kind Memory_>
-struct Store<Scalar_, Lanes_, Memory_, true, 4> {
- /// The output type.
- typedef typename Vectorize<Scalar_, Lanes_>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void store(AccessType const& src, Scalar_* pointer, int offset) {
- uint32_t* addr = reinterpret_cast<uint32_t*>(&pointer[offset]);
- addr[0] = src.registers[0];
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int Lanes_, MemorySpace::Kind Memory_>
-struct Store<Scalar_, Lanes_, Memory_, true, 8> {
- /// The output type.
- typedef typename Vectorize<Scalar_, Lanes_>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void store(AccessType const& src, Scalar_* pointer, int offset) {
- uint2* addr = reinterpret_cast<uint2*>(&pointer[offset]);
- addr[0] = make_uint2(src.registers[0], src.registers[1]);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <MemorySpace::Kind Memory_>
-struct Store<double, 2, Memory_, true, 16> {
- /// The output type.
- typedef typename Vectorize<double, 2>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void store(AccessType const& src, double* pointer, int offset) {
- double2* addr = reinterpret_cast<double2*>(&pointer[offset]);
- addr[0] = make_double2(src[0], src[1]);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int Lanes_, MemorySpace::Kind Memory_>
-struct Store<Scalar_, Lanes_, Memory_, true, 16> {
- /// The output type.
- typedef typename Vectorize<Scalar_, Lanes_>::Type AccessType;
-
- /// The store function.
- static CUTLASS_DEVICE void store(AccessType const& src, Scalar_* pointer, int offset) {
- uint4* addr = reinterpret_cast<uint4*>(&pointer[offset]);
- addr[0] = make_uint4(src.registers[0], src.registers[1], src.registers[2], src.registers[3]);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/matrix_traits.h b/cutlass-example/cutlass/matrix_traits.h
deleted file mode 100644
index 77e8b70..0000000
--- a/cutlass-example/cutlass/matrix_traits.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines properties of matrices used to denote layout and operands to GEMM kernels.
-*/
-#pragma once
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Describes layouts of matrices
-struct MatrixLayout {
- enum Kind { kRowMajor, kColumnMajor };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Gemm operand - D = A * B + C
-struct GemmOperand {
- enum Kind { kA, kB, kC, kD };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/predicate_vector.h b/cutlass-example/cutlass/predicate_vector.h
deleted file mode 100644
index 8166857..0000000
--- a/cutlass-example/cutlass/predicate_vector.h
+++ /dev/null
@@ -1,493 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines container classes and iterators for managing a statically sized vector
- of boolean predicates.
-*/
-#pragma once
-
-#include <stdint.h>
-
-#include <cutlass/cutlass.h>
-#include <cutlass/shape.h>
-
-#include <cutlass/util/platform.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup predicate_vector_concept Predicate Vector Concept
-@{
-
-Implementations of \ref predicate_vector_concept contain an ordered set of boolean predicates which
-may be used as conditionals in other device-side operations. Both random access and iterators
-offering sequential access are provided.
-
-@par Predicate Vector
- A \ref predicate_vector_concept satisfies the following expressions
- - <b>at(int idx)</b> - returns the value of the indexed predicate
- - <b>set(int idx, bool value)</b> - sets the value of the indexed predicate
- - <b>begin()</b> - returns a \ref predicate_iterator_concept pointing to the first predicate
-
-@}
-*/
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup predicate_iterator_concept Predicate Iterator Concept
-@{
-
-Implementations of \ref predicate_iterator_concept enables accessing and traversing elements of a
-bit vector.
-
-@par Const Predicate Iterator
- A const \ref predicate_iterator_concept satisfies the following expressions
- - <b>++it</b> increments the iterator to the next predicate
- - <b>*it</b> returns the value of the currently pointed-to predicate
-
-@par Mutable Predicate Iterator
- A \ref predicate_iterator_concept that is non-const <b>also</b> satisfies the following expressions
- - <b>it.set(bool value)</b> sets the value of the currently pointed-to predicate
-
-@}
-*/
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup predicate_tile_adapter Predicate Tile Adapter Concept
-@{
-
-Implementations of \ref predicate_tile_adapter provide a mapping between a the elements of a \ref
-tile_traits_concept and a \ref predicate_vector_concept.
-
-@par Predicate Tile Adapter
- A \ref predicate_tile_adapter satisfies the following expressions
- - <b>at(int d, int h, int w, int c)</b> - returns the value of a predicate corresponding to the
- access (d, h, w, c) within the tile.
-
-@}
-*/
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Statically sized array of bits implementing @concept{predicate_vector_concept}.
-template <
- /// Number of predicates conatined in predicate vector
- int kPredicates_,
- /// Number of predicates contained in each byte of internal storage
- int kPredicatesPerByte_ = 4,
- /// Location of first predicate within byte of internal storage
- int kPredicateStart_ = 0>
-struct PredicateVector {
- /// Number of bits stored by the PredicateVector
- static int const kPredicates = kPredicates_;
-
- /// Number of bits stored within each byte of the predicate bit vector
- static int const kPredicatesPerByte = kPredicatesPerByte_;
-
- /// First bit withing each byte containing predicates
- static int const kPredicateStart = kPredicateStart_;
-
- // Make sure no one tries to put more than 8 bits in a byte :)
- static_assert(kPredicatesPerByte <= 8, "kPredicatesPerByte must fit within an actual byte");
- // Make sure the "offsetted" bits fit in one byte.
- static_assert(kPredicateStart + kPredicatesPerByte < 8,
- "The offsetted predicates must fit within an actual byte.");
-
- /// Storage type of individual elements
- typedef uint32_t Storage;
-
- /// Number of bytes needed
- static int const kBytes = (kPredicates + kPredicatesPerByte - 1) / kPredicatesPerByte;
-
- /// Number of storage elements needed
- static int const kWordCount = (kBytes + sizeof(Storage) - 1) / sizeof(Storage);
-
- private:
- //
- // Data members
- //
-
- /// Words of bit vector
- Storage storageData[kWordCount];
-
- //
- // Methods
- //
-
- /// Computes the word and bit corresponding to a logical predicate index
- CUTLASS_HOST_DEVICE void computeStorageOffset(int &word, int &bit, int idx) const {
- CUTLASS_ASSERT(idx < kPredicates);
-
- int byte = (idx / kPredicatesPerByte);
- int bit_offset = (idx % kPredicatesPerByte);
-
- word = byte / sizeof(Storage);
- int byte_offset = (byte % sizeof(Storage));
-
- bit = byte_offset * 8 + bit_offset + kPredicateStart;
- }
-
- /// Accesses a given word with optional assertions
- CUTLASS_HOST_DEVICE Storage &storage(int word) {
- CUTLASS_ASSERT(word < kWordCount);
- return storageData[word];
- }
-
- /// Accesses a given word with optional assertions
- CUTLASS_HOST_DEVICE Storage const &storage(int word) const {
- CUTLASS_ASSERT(word < kWordCount);
- return storageData[word];
- }
-
- public:
- //
- // Iterator
- //
-
- /**
- * @brief A const iterator implementing \ref predicate_iterator_concept enabling sequential
- * read-only access to prediactes.
- * @concept{predicate_iterator_concept}
- */
- class ConstIterator {
- /// Reference to PredicateVector instance
- PredicateVector const &vec_;
-
- /// Index into PredicateVector
- int bit_;
-
- public:
- /// Copy constructor
- CUTLASS_HOST_DEVICE
- ConstIterator(ConstIterator const &it) : vec_(it.vec_), bit_(it.bit_) {}
-
- ///
- CUTLASS_HOST_DEVICE
- ConstIterator(PredicateVector const &_vec, int _start = 0) : vec_(_vec), bit_(_start) {}
-
- /// Pre-increment
- CUTLASS_HOST_DEVICE
- ConstIterator &operator++() {
- ++bit_;
- return *this;
- }
-
- /// Pre-decrement
- CUTLASS_HOST_DEVICE
- ConstIterator &operator--() {
- --bit_;
- return *this;
- }
-
- /// Post-increment
- CUTLASS_HOST_DEVICE
- ConstIterator operator++(int) {
- ConstIterator ret(*this);
- ret.bit_++;
- return ret;
- }
-
- /// Post-decrement
- CUTLASS_HOST_DEVICE
- ConstIterator operator--(int) {
- ConstIterator ret(*this);
- ret.bit_--;
- return ret;
- }
-
- /// Returns true if iterators point to the same bit
- CUTLASS_HOST_DEVICE
- bool operator==(ConstIterator const &it) const { return bit_ == it.bit_; }
-
- /// Returns false if iterators point to the same bit
- CUTLASS_HOST_DEVICE
- bool operator!=(ConstIterator const &it) const { return bit_ != it.bit_; }
-
- /// Dereferences iterator
- CUTLASS_HOST_DEVICE
- bool operator*() const { return vec_[bit_]; }
- };
-
- /**
- * @brief An iterator implementing \ref predicate_iterator_concept enabling sequential
- * read and write access to predicates.
- * @concept{predicate_iterator_concept}
- */
- class Iterator {
- /// Reference to PredicateVector instance
- PredicateVector &vec_;
-
- /// Index into PredicateVector
- int bit_;
-
- public:
- /// Copy constructor
- CUTLASS_HOST_DEVICE
- Iterator(Iterator const &it) : vec_(it.vec_), bit_(it.bit_) {}
-
- /// Constructs an iterator from a PredicateVector
- CUTLASS_HOST_DEVICE
- Iterator(PredicateVector &_vec, int _start = 0) : vec_(_vec), bit_(_start) {}
-
- /// Pre-increment
- CUTLASS_HOST_DEVICE
- Iterator &operator++() {
- ++bit_;
- return *this;
- }
-
- /// Pre-decrement
- CUTLASS_HOST_DEVICE
- Iterator &operator--() {
- --bit_;
- return *this;
- }
-
- /// Post-increment
- CUTLASS_HOST_DEVICE
- Iterator operator++(int) {
- Iterator ret(*this);
- ret.bit_++;
- return ret;
- }
-
- /// Post-decrement
- CUTLASS_HOST_DEVICE
- Iterator operator--(int) {
- Iterator ret(*this);
- ret.bit_--;
- return ret;
- }
-
- /// Returns true if iterators point to the same bit
- CUTLASS_HOST_DEVICE
- bool operator==(Iterator const &it) const { return bit_ == it.bit_; }
-
- /// Returns false if iterators point to the same bit
- CUTLASS_HOST_DEVICE
- bool operator!=(Iterator const &it) const { return bit_ != it.bit_; }
-
- /// Gets the bit at the pointed to location
- CUTLASS_HOST_DEVICE
- bool get() { return vec_[bit_]; }
-
- /// Dereferences iterator
- CUTLASS_HOST_DEVICE
- bool operator*() const { return vec_[bit_]; }
-
- /// Sets the bit at the pointed to location
- CUTLASS_HOST_DEVICE
- void set(bool value = true) { vec_.set(bit_, value); }
- };
-
- /// Iterator that always returns true
- struct TrivialIterator {
- /// Constructor
- CUTLASS_HOST_DEVICE
- TrivialIterator() {}
-
- /// Copy constructor
- CUTLASS_HOST_DEVICE
- TrivialIterator(Iterator const &it) {}
-
- /// Constructs an iterator from a PredicateVector
- CUTLASS_HOST_DEVICE
- TrivialIterator(PredicateVector const &_vec) {}
-
- /// Pre-increment
- CUTLASS_HOST_DEVICE
- TrivialIterator &operator++() { return *this; }
-
- /// Post-increment
- CUTLASS_HOST_DEVICE
- TrivialIterator operator++(int) { return *this; }
-
- /// Dereferences iterator
- CUTLASS_HOST_DEVICE
- bool operator*() const { return true; }
- };
-
- public:
- //
- // Methods
- //
-
- /// Initialize the predicate vector
- CUTLASS_HOST_DEVICE PredicateVector(bool value = true) { fill(value); }
-
- /// Fills all predicates with a given value
- CUTLASS_HOST_DEVICE void fill(bool value = true) {
- Storage item = (value ? ~Storage(0) : Storage(0));
-
- CUTLASS_PRAGMA_UNROLL
- for (int i = 0; i < kWordCount; ++i) {
- storage(i) = item;
- }
- }
-
- /// Accesses a bit within the predicate vector.
- CUTLASS_HOST_DEVICE bool operator[](int idx) const { return at(idx); }
-
- /// Accesses a bit within the predicate vector.
- CUTLASS_HOST_DEVICE bool at(int idx) const {
- int bit, word;
- computeStorageOffset(word, bit, idx);
-
- return ((storage(word) >> bit) & 1);
- }
-
- /// Set a bit within the predicate vector.
- CUTLASS_HOST_DEVICE void set(int idx, bool value = true) {
- int bit, word;
- computeStorageOffset(word, bit, idx);
-
- Storage disable_mask = (~(Storage(1) << bit));
- Storage enable_mask = (Storage(value) << bit);
-
- storage(word) = ((storage(word) & disable_mask) | enable_mask);
- }
-
- /// Computes the intersection of two identical predicate vectors.
- CUTLASS_HOST_DEVICE PredicateVector &operator&=(PredicateVector const &predicates) {
- CUTLASS_PRAGMA_UNROLL
- for (int i = 0; i < kWordCount; ++i) {
- storage(i) = (storage(i) & predicates.storage(i));
- }
- return *this;
- }
-
- /// Computes the union of two identical predicate vectors.
- CUTLASS_HOST_DEVICE PredicateVector &operator|=(PredicateVector const &predicates) {
- CUTLASS_PRAGMA_UNROLL
- for (int i = 0; i < kWordCount; ++i) {
- storage(i) = (storage(i) | predicates.storage(i));
- }
- return *this;
- }
-
- /// Returns true if entire predicate array is zero.
- CUTLASS_HOST_DEVICE bool is_zero() const {
- Storage mask(0);
- for (int byte = 0; byte < sizeof(Storage); ++byte) {
- Storage byte_mask = (((1 << kPredicatesPerByte) - 1) << kPredicateStart);
- mask |= (byte_mask << (byte * 8));
- }
- uint32_t result = 0;
- for (int word = 0; word < kWordCount; ++word) {
- result |= storage(word);
- }
- return result == 0;
- }
-
- /// Returns an iterator to the start of the bit vector
- CUTLASS_DEVICE
- Iterator begin() { return Iterator(*this); }
-
- /// Returns an iterator
- CUTLASS_DEVICE
- Iterator end() { return Iterator(*this, kPredicates); }
-
- /// Returns a ConstIterator
- CUTLASS_DEVICE
- ConstIterator const_begin() const { return ConstIterator(*this); }
-
- /// Returns a ConstIterator
- CUTLASS_DEVICE
- ConstIterator const_end() const { return ConstIterator(*this, kPredicates); }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Always returns true predicate.
-struct TrivialPredicateTileAdapter {
- /// Ctor.
- CUTLASS_HOST_DEVICE TrivialPredicateTileAdapter() {}
-
- /// The value at location (d, h, w, c).
- CUTLASS_HOST_DEVICE bool at(int, int, int, int) const { return true; }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Adapter to enable random access to predicates via logical coordinate within a tile.
-template <typename PredicateVector_, typename Iterations_>
-struct PredicateTileAdapter {
- /// The vector of predicates.
- typedef PredicateVector_ PredicateVector;
- /// The iterations.
- typedef Iterations_ Iterations;
-
- private:
- /// The predicates.
- PredicateVector &predicates;
-
- public:
- /// Ctor.
- CUTLASS_DEVICE PredicateTileAdapter(PredicateVector &predicates_) : predicates(predicates_) {}
-
- /// Get the value at location (d, h, w, c).
- CUTLASS_DEVICE bool at(int d, int h, int w, int c) const {
- int const bit = ComputeOffsetFromShape<Iterations>::get(d, h, w, c);
- return predicates.at(bit);
- }
-
- /// Set the value at location (d, h, w, c).
- CUTLASS_DEVICE void set(int d, int h, int w, int c, bool value) {
- int const bit = ComputeOffsetFromShape<Iterations>::get(d, h, w, c);
- predicates.set(bit, value);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Adapter to enable random access to predicates via logical coordinate within a tile.
-template <typename PredicateVector_, typename Iterations_>
-struct ConstPredicateTileAdapter {
- /// The vector of predicates.
- typedef PredicateVector_ PredicateVector;
- /// The iterations.
- typedef Iterations_ Iterations;
-
- private:
- /// The predicates.
- PredicateVector const &predicates;
-
- public:
- /// Ctor.
- CUTLASS_DEVICE ConstPredicateTileAdapter(PredicateVector const &predicates_)
- : predicates(predicates_) {}
-
- /// Get the value at location (d, h, w, c).
- CUTLASS_DEVICE bool at(int d, int h, int w, int c) const {
- int const bit = ComputeOffsetFromShape<Iterations>::get(d, h, w, c);
- return predicates.at(bit);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/reshape_tile.h b/cutlass-example/cutlass/reshape_tile.h
deleted file mode 100644
index 55aebfc..0000000
--- a/cutlass-example/cutlass/reshape_tile.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines a type for restructuring a tile.
-*/
-#pragma once
-
-#include <cutlass/shape.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// The following functor reshapes a tile of data. The goal is to have at least kAccessSize in
-// the inner-most dimension. If the user respects that constraint, there is nothing to be done. If
-// that's not the case, this functor will correct that and "extract" the right number of elements
-// from the next dimension.
-
-template <typename Tile_, int kAccessSize_, bool = (Tile_::kC < kAccessSize_)>
-struct ReshapeTile {
- typedef Tile_ Tile;
-};
-
-template <typename Tile_, int kAccessSize_>
-struct ReshapeTile<Tile_, kAccessSize_, true> {
- // Make sure the W dimension of the tile is large enough.
- static_assert(Tile_::kW >= kAccessSize_, "The W dimension is too small");
- // Make sure the dimension can be divided by the number of scalars.
- static_assert(Tile_::kW % kAccessSize_ == 0, "Not supported");
- // Collapse the W dimension.
- typedef Shape<Tile_::kD, Tile_::kH, Tile_::kW / kAccessSize_, kAccessSize_> Tile;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/shape.h b/cutlass-example/cutlass/shape.h
deleted file mode 100644
index 4f6b222..0000000
--- a/cutlass-example/cutlass/shape.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines Shape implementing the Layout concept for representing a 4D hypercube of objects.
-*/
-#pragma once
-
-#include <cutlass/cutlass.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup layout_concept Layout Concept
-* @{
-* @par Implementations of \ref layout_concept are used to describe a cube with DxHxW elements and C
-scalars per element.
- A HxW slice of a cube is called an image and a cube consists of D images.
-*
-* @par Notations
-* Let Layout be an implementation of the \ref layout_concept.
-*
-* @par Valid Expressions
-* - <b>Layout::D</b> specifies the depth of a cube
-* - <b>Layout::H</b> specifies the height of a cube
-* - <b>Layout::W</b> specifies the height of a cube
-* - <b>Layout::C</b> specifies the number of channels of each element in a cube
-* - <b>Layout::W_c</b> specifies the number of scalars of each row in one image of a cube.
-* - <b>Layout::H_w</b> specifies the number of elements in an image slice.
-* - <b>Layout::H_w_c</b>_specifies the number of scalars in an image slice.
-* - <b>Layout::D_h_w</b> specifies the number of elements in a cube.
-* - <b>Layout::D_h_w_c</b> specifies the number of scalars in a cube.
-* - <b>Layout::Strides</b> is a \ref layout_concept specifying the strides.
-* @}
-*/
-
-/**
-* @brief A Shape implementing \ref layout_concept describing the dimensions of a cube.
-* @concept{layout_concept}
-*/
-template <int kD_ = 1, int kH_ = 1, int kW_ = 1, int kC_ = 1>
-struct Shape {
- /// The depth of the cube.
- static int const kD = kD_;
- /// The height of the cube.
- static int const kH = kH_;
- /// The width of the cube.
- static int const kW = kW_;
- /// The number of scalars per element.
- static int const kC = kC_;
-};
-
-/**
-* @brief Compute derived counted of a \ref layout_concept based class
-*/
-template <typename Shape>
-struct ShapeCount {
- /// The number of elements per row.
- static int const kWc = Shape::kW * Shape::kC;
- /// The number of pixels per image.
- static int const kHw = Shape::kH * Shape::kW;
- /// The number of elements per image.
- static int const kHwc = Shape::kH * kWc;
- /// The number of pixels per cube.
- static int const kDhw = Shape::kD * kHw;
- /// The number of elements in the 4D space.
- static int const kDhwc = Shape::kD * kHwc;
- /// The number of elements in the 4D space.
- static int const kCount = kDhwc;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename A_, int kScale_>
-struct ShapeScale {
- typedef Shape<A_::kD * kScale_, A_::kH * kScale_, A_::kW * kScale_, A_::kC * kScale_> Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename A_, typename B_>
-struct ShapeAdd {
- typedef Shape<A_::kD + B_::kD, A_::kH + B_::kH, A_::kW + B_::kW, A_::kC + B_::kC> Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename A_, typename B_>
-struct ShapeSub {
- typedef Shape<A_::kD - B_::kD, A_::kH - B_::kH, A_::kW - B_::kW, A_::kC - B_::kC> Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename A_, typename B_>
-struct ShapeMul {
- typedef Shape<A_::kD * B_::kD, A_::kH * B_::kH, A_::kW * B_::kW, A_::kC * B_::kC> Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename A_, typename B_>
-struct ShapeDiv {
- typedef Shape<A_::kD / B_::kD, A_::kH / B_::kH, A_::kW / B_::kW, A_::kC / B_::kC> Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename A_, typename B_>
-struct ShapeMax {
- typedef Shape<(A_::kD > B_::kD ? A_::kD : B_::kD),
- (A_::kH > B_::kH ? A_::kH : B_::kH),
- (A_::kW > B_::kW ? A_::kW : B_::kW),
- (A_::kC > B_::kC ? A_::kC : B_::kC)>
- Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename A_, typename B_>
-struct ShapeMin {
- typedef Shape<(A_::kD < B_::kD ? A_::kD : B_::kD),
- (A_::kH < B_::kH ? A_::kH : B_::kH),
- (A_::kW < B_::kW ? A_::kW : B_::kW),
- (A_::kC < B_::kC ? A_::kC : B_::kC)>
- Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Shape_, int kElementsPerAccess>
-struct ShapeStrides {
- typedef Shape<Shape_::kH * Shape_::kW * Shape_::kC,
- Shape_::kW * Shape_::kC,
- Shape_::kC,
- kElementsPerAccess>
- Shape;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief Compute the offset for the given coordinates in a cube
-* @tparam A \ref layout_concept where each dimension of the cube specifies the corresponding stride.
-*/
-template <typename Shape_>
-struct ComputeOffsetFromShape {
- static CUTLASS_DEVICE int get(int d, int h, int w, int c) {
- // clang-format off
- return d * Shape_::kH * Shape_::kW * Shape_::kC +
- h * Shape_::kW * Shape_::kC +
- w * Shape_::kC +
- c;
- // clang-format on
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief Compute the offset for the given coordinates in a cube with a depth of 1
-* @tparam kSh Elements in the H dimension
-* @tparam kSw Elements in the W dimension
-* @tparam kSc Separation between two elements in "elements"
-*/
-template <int kSh_, int kSw_, int kSc_>
-struct ComputeOffsetFromShape<Shape<1, kSh_, kSw_, kSc_> > {
- static CUTLASS_DEVICE int get(int d, int h, int w, int c) {
- return h * kSw_ * kSc_ + w * kSc_ + c;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief Compute the offset for the given coordinates in a cube with one channel and a depth of 1
-* @tparam kSh Elements in the H dimension
-* @tparam kSw Elements in the W dimension
-*/
-template <int kSh_, int kSw_>
-struct ComputeOffsetFromShape<Shape<1, kSh_, kSw_, 1> > {
- static CUTLASS_DEVICE int get(int d, int h, int w, int c) { return h * kSw_ + w; }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief Compute the offset for the given coordinates in a cube
-* @tparam A \ref layout_concept where each dimension of the cube specifies the corresponding stride.
-*/
-template <typename Strides_>
-struct ComputeOffsetFromStrides {
- static CUTLASS_DEVICE int get(int d, int h, int w, int c) {
- return d * Strides_::kD + h * Strides_::kH + w * Strides_::kW + c * Strides_::kC;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief Compute the offset for the given coordinates in a cube with a depth of 1
-* @tparam S_h Stride in the H dimension in scalars
-* @tparam S_w Stride in the W dimension in scalars
-* @tparam S_c Stride between two scalars.
-*/
-template <int S_h_, int S_w_, int S_c_>
-struct ComputeOffsetFromStrides<Shape<1, S_h_, S_w_, S_c_> > {
- static CUTLASS_DEVICE int get(int d, int h, int w, int c) {
- return h * S_h_ + w * S_w_ + c * S_c_;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief Compute the offset for the given coordinates in a cube with one channel and a depth of 1
-* @tparam S_h Stride in the H dimension in scalars
-* @tparam S_w Stride in the W dimension in scalars
-*/
-template <int S_h_, int S_w_>
-struct ComputeOffsetFromStrides<Shape<1, S_h_, S_w_, 1> > {
- static CUTLASS_DEVICE int get(int d, int h, int w, int c) { return h * S_h_ + w * S_w_; }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief Decompose threadId.x into coordinate of a cube whose dimensions are specified by Threads_.
-* Afterwards compute the offset of those coordinates using Strides_
-* @tparam Threads_ The dimension of the cube the threadIdx.x value is mapped on
-* @tparam Strides_ The strides to use when compute the offsets based on the coordinates of the cube.
-*/
-template <typename Threads_, typename Strides_>
-struct ComputeThreadOffsetFromStrides {
- static CUTLASS_DEVICE int get() {
- // Decompose the thread index.
- int c = threadIdx.x % Threads_::kC;
- int w = threadIdx.x / Threads_::kC % Threads_::kW;
- int h = threadIdx.x / Threads_::kC / Threads_::kW % Threads_::kH;
- int d = threadIdx.x / Threads_::kC / Threads_::kW / Threads_::kH;
-
- // Compute the offset.
- return d * Strides_::kD + h * Strides_::kH + w * Strides_::kW + c * Strides_::kC;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-/**
-*@brief Specialization for D=1
-*/
-template <int T_h_, int T_w_, int T_c_, int S_h_, int S_w_, int S_c_>
-struct ComputeThreadOffsetFromStrides<Shape<1, T_h_, T_w_, T_c_>, Shape<1, S_h_, S_w_, S_c_> > {
- static CUTLASS_DEVICE int get() {
- // Decompose the thread index.
- int c = threadIdx.x % T_c_;
- int w = threadIdx.x / T_c_ % T_w_;
- int h = threadIdx.x / T_c_ / T_w_ % T_h_;
-
- // Compute the offset.
- return h * S_h_ + w * S_w_ + c * S_c_;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-*@brief Specialization for D=1 and C=1
-*/
-template <int T_h_, int T_w_, int S_h_, int S_w_>
-struct ComputeThreadOffsetFromStrides<Shape<1, T_h_, T_w_, 1>, Shape<1, S_h_, S_w_, 1> > {
- static CUTLASS_DEVICE int get() {
- // Decompose the thread index.
- int w = threadIdx.x % T_w_;
- int h = threadIdx.x / T_w_;
-
- // Compute the offset.
- return h * S_h_ + w * S_w_;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/tensor_ref.h b/cutlass-example/cutlass/tensor_ref.h
deleted file mode 100644
index 8ef31e3..0000000
--- a/cutlass-example/cutlass/tensor_ref.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines a structure containing strides, bounds, and a pointer to tensor data.
-*/
-#pragma once
-
-#include <typeinfo>
-
-#include <cutlass/coord.h>
-#include <cutlass/cutlass.h>
-#include <cutlass/vector.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Structure modeling a pointer and stride into a tensor
-template <typename Storage_, int Rank_>
-class TensorRef {
- public:
- /// Data type of individual access
- typedef Storage_ Storage;
-
- /// Rank of tensor
- static int const Rank = Rank_;
-
- private:
- //
- // Data members
- //
-
- /// Pointer to storage element
- Storage* ptr_;
-
- /// Stride information
- Coord<Rank> stride_;
-
- public:
- //
- // Methods
- //
-
- /// Default ctor
- CUTLASS_HOST_DEVICE
- TensorRef() : ptr_(nullptr) {}
-
- /// Constructs from a pointer, size, and stride
- CUTLASS_HOST_DEVICE
- TensorRef(Storage* ptr, Coord<Rank> stride) : ptr_(ptr), stride_(stride) {}
-
- /// Updates the pointer, stride, and location within a TensorRef
- CUTLASS_HOST_DEVICE
- void reset(Storage* ptr = nullptr, Coord<Rank> stride = Coord<Rank>(0)) {
- ptr_ = ptr;
- stride_ = stride;
- }
-
- /// Conversion function
- template <typename T>
- TensorRef<T, Rank> convert() {
- Coord<Rank> converted_stride;
- for (int i = 0; i < Rank - 1; ++i) {
- converted_stride[i] = stride_[i] * Extent<Storage>::kValue / Extent<T>::kValue;
- }
- converted_stride[Rank - 1] = stride_[Rank - 1];
-
- return TensorRef<T, Rank>(reinterpret_cast<T*>(ptr_), converted_stride);
- }
-
- /// Returns true if the TensorRef may be safely accessed
- CUTLASS_HOST_DEVICE
- bool good() const { return ptr_ != nullptr; }
-
- /// Returns the pointer to referenced data
- CUTLASS_HOST_DEVICE
- Storage* data() const { return ptr_; }
-
- /// Returns the stride of the tensor
- CUTLASS_HOST_DEVICE
- Coord<Rank> const& stride() const { return stride_; }
-
- /// Returns the stride of the tensor in the given dimension
- CUTLASS_HOST_DEVICE
- int const& stride(int dim) const { return stride_.at(dim); }
-
- /// Returns the maximum stride element as the 'leading dimension'
- CUTLASS_HOST_DEVICE
- int leading_dim() const { return __NV_STD_MAX(stride_[1], stride_[2]); }
-
- /// Computes the offset of an index from the origin of the tensor
- CUTLASS_HOST_DEVICE
- long long offset(Coord<Rank> const& coord) const {
- return stride_.template dot<long long>(coord);
- }
-
- /// Returns a reference to the element at a given Coord
- CUTLASS_HOST_DEVICE
- Storage& at(Coord<Rank> const& coord) const { return ptr_[offset(coord)]; }
-
- /// Element-wise accessor
- Storage& operator[](Coord<Rank> const& coord) const { return at(coord); }
-
- /// Returns a reference to the element at a given Coord
- CUTLASS_HOST_DEVICE
- Storage& at(int idx) const { return ptr_[idx]; }
-
- /// Element-wise accessor
- Storage& operator[](int idx) const { return at(idx); }
-
- /// Adds an offset to the pointer
- CUTLASS_HOST_DEVICE
- TensorRef& advance(Coord<Rank> const& b) {
- ptr_ += offset(b);
- return *this;
- }
-
- /// Returns a TensorRef offset by a given amount
- CUTLASS_HOST_DEVICE
- TensorRef operator+(Coord<Rank> const& b) const { return TensorRef(ptr_ + offset(b), stride_); }
-
- /// Returns a TensorRef offset by a given amount
- CUTLASS_HOST_DEVICE
- TensorRef operator-(Coord<Rank> const& b) const { return TensorRef(ptr_ - offset(b), stride_); }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/tensor_view.h b/cutlass-example/cutlass/tensor_view.h
deleted file mode 100644
index 89c6bd5..0000000
--- a/cutlass-example/cutlass/tensor_view.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines a structure containing strides and a pointer to tensor data.
-*/
-
-#pragma once
-
-#include <cmath>
-
-#include <cutlass/cutlass.h>
-#include <cutlass/tensor_ref.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Host-side reference implementation of tensor operations
-template <typename T>
-class TensorView : public TensorRef<T, 4> {
- public:
- /// Reference and stride
- typedef TensorRef<T, 4> Base;
-
- /// Reference and stride
- typedef Base TensorRef_t;
-
- /// Reference to constant type
- typedef TensorRef<T const, 4> ConstTensorRef_t;
-
- /// Rank of tensor
- static int const Rank = TensorRef_t::Rank;
-
- /// Type used to compute the offset of an element to the base of a tensor
- typedef int Offset_t;
-
- /// Coordinate into tensor
- typedef Coord<Rank> Coord_t;
-
- private:
- //
- // Data members
- //
-
- /// Pointer to pitch-linear memory
- TensorRef_t ref_;
-
- /// Dimensions of coordinate (independent of stride)
- Coord_t size_;
-
- public:
- //
- // Device and Host Methods
- //
-
- /// Default constructor
- CUTLASS_HOST_DEVICE
- TensorView() {}
-
- /// Constructs a Tensor_view from a TensorRef and size
- CUTLASS_HOST_DEVICE
- TensorView(TensorRef_t const& _ref, Coord_t const& _size) : Base(_ref), size_(_size) {}
-
- /// Returns true if the Tensor_view is bound to some memory
- CUTLASS_HOST_DEVICE
- bool good() const { return ref().good(); }
-
- /// Returns a pointer to data
- CUTLASS_HOST_DEVICE
- T* data() const { return ref().data(); }
-
- /// Updates the reference and size of a Tensor_view object
- CUTLASS_HOST_DEVICE
- void reset(TensorRef_t const& _ref = TensorRef_t(0), Coord_t const& _size = Coord_t()) {
- Base::operator=(_ref);
- size_ = _size;
- }
-
- /// Accesses the tensor reference pointing to data
- CUTLASS_HOST_DEVICE
- TensorRef_t& ref() { return *this; }
-
- ///
- CUTLASS_HOST_DEVICE
- ConstTensorRef_t const_ref() { return ConstTensorRef_t(data(), stride()); }
-
- /// Accesses the tensor reference pointing to data
- CUTLASS_HOST_DEVICE
- TensorRef_t const& ref() const { return *this; }
-
- /// Accesses the size
- CUTLASS_HOST_DEVICE
- Coord_t const& size() const { return size_; }
-
- /// Accesses the size
- CUTLASS_HOST_DEVICE
- int size(int dim) const { return size_.at(dim); }
-
- /// Accesses the stride
- CUTLASS_HOST_DEVICE
- Coord_t const& stride() const { return ref().stride(); }
-
- /// Accesses the stride
- CUTLASS_HOST_DEVICE
- int const& stride(int dim) const { return ref().stride(dim); }
-
- /// Assigns the Tensor_view
- CUTLASS_HOST_DEVICE
- TensorView& operator=(TensorView const& _tensor) {
- Base::operator=(_tensor._ref);
- size_ = _tensor.size_;
- return *this;
- }
-
- /// Returns the index of an element
- CUTLASS_HOST_DEVICE
- Offset_t offset(Coord_t const& coord) const { return ref().offset(coord); }
-
- /// Determines whether a location is within a tensor
- CUTLASS_HOST_DEVICE
- bool contains(Coord_t const& coord) const {
- for (int dim = 0; dim < Rank; ++dim) {
- if (coord.at(dim) >= size_.at(dim)) {
- return false;
- }
- }
- return true;
- }
-
- /// Element-wise accessor
- CUTLASS_HOST_DEVICE
- T& at(Coord_t const& coord) const { return ref().at(coord); }
-
- /// Element-wise accessor
- T& operator[](Coord<Rank> const& coord) const { return at(coord); }
-
- /// Element-wise accessor
- CUTLASS_HOST_DEVICE
- T& at(Offset_t idx) const { return ref().at(idx); }
-
- /// Returns a Tensor_view given location and size quantities
- CUTLASS_HOST_DEVICE
- TensorView<T> subview(Coord_t const& location, Coord_t size) const {
- return TensorView<T>(ref() + location, size.clamp(size_ - location));
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/tile_iterator.h b/cutlass-example/cutlass/tile_iterator.h
deleted file mode 100644
index 5d39c4f..0000000
--- a/cutlass-example/cutlass/tile_iterator.h
+++ /dev/null
@@ -1,899 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines the Tile Traits concept and iterators for loading and storing to tiles
- efficiently.
-*/
-#pragma once
-
-#include <cutlass/fragment.h>
-#include <cutlass/load_store.h>
-#include <cutlass/predicate_vector.h>
-#include <cutlass/vector.h>
-
-namespace cutlass {
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup tile_traits_concept Tile Traits Concept
-@{
-
-\ref tile_traits_concept is a type definining the shape of a tile and the distribution of accesses
-by individual entities, either threads or other.
-
-@par Tile Traits Concept
- Types satisfying \ref tile_traits_concept define the following members
- - <b>Tile</b> - a type satisfying \ref layout_concept describing the dimensions of the tile
- - <b>Delta</b> - a type satisfying \ref layout_concept describing the increments between accesses
-along each dimension
- - <b>Iterations</b> - a type satisfying \ref layout_concept describing the number of accesses
-along each dimension
- - <b>Offset</b> - the type of a <i>functor</i> computing the offset of each participating entity
-as a Coord<4>.
-@}
-*/
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Specifies dimension in which post-increment accesses advance
-struct IteratorAdvance {
- enum Kind { kD, kH, kW };
-};
-
-/// Specifies whether iterator storage fragment consists of Scalar values or WMMA matrix
-struct IteratorFragment {
- enum Kind { kScalar, kWmmaMatrix };
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief A template defining \ref tile_traits_concept
-* @concept{tile_traits_concept}
-*/
-template <typename Tile_,
- typename Delta_,
- typename Iterations_,
- typename ThreadOffset_,
- int kAccessSize>
-struct TileTraits {
- /// Shape of the tile
- typedef Tile_ Tile;
-
- /// Number of steps between accesses along each dimension
- typedef Delta_ Delta;
-
- /// Number of accesses performed
- typedef Iterations_ Iterations;
-
- /// Functor that returns the logical coordinate of each entity's initial offset in the tile
- typedef ThreadOffset_ ThreadOffset;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Iterator for accessing a stripmined tile in memory
-template <typename Traits_,
- typename Scalar_,
- IteratorAdvance::Kind Advance_ = IteratorAdvance::kH,
- MemorySpace::Kind MemorySpace = MemorySpace::kGeneric,
- typename Index_ = int,
- typename FragmentElement_ = Scalar_,
- IteratorFragment::Kind IteratorFragment_ = IteratorFragment::kScalar,
- typename Skew_ = Shape<0, 0, 0, 0> >
-struct TileIteratorBase {
- /// concept TileTraits
- typedef Traits_ Traits;
-
- /// Scalar element
- typedef Scalar_ Scalar;
-
- /// Fragment element
- typedef FragmentElement_ FragmentElement;
-
- /// Specifies dimension in which post-increment accesses advance.
- static IteratorAdvance::Kind const kAdvance = Advance_;
-
- /// Specifies iterator storage fragment type (Scalar or WmmaMatrix)
- static IteratorFragment::Kind const kIteratorFragment = IteratorFragment_;
-
- /// Source or destination memory space
- static MemorySpace::Kind const kMemorySpace = MemorySpace;
-
- /// Index type
- typedef Index_ Index;
-
- /// Skew quantity
- typedef Skew_ Skew;
-
- /// Tile shape
- typedef typename Traits::Tile Tile;
-
- /// Distance along each dimension
- typedef typename Traits::Delta Delta;
-
- /// The strides in each dimension between different loads/stores.
- typedef typename Traits::ImmediateOffsetStrides ImmediateOffsetStrides;
-
- /// Iterations
- typedef typename Traits::Iterations Iterations;
-
- /// Thread offset
- typedef typename Traits::ThreadOffset ThreadOffset;
-
- /// The number of scalars accessed per load/store.
- static int const kAccessSize = Tile::kC;
-
- /// The elements loaded/store by one instruction.
- typedef typename Vectorize<FragmentElement, kAccessSize>::Type AccessType;
-
- /// The size of storage needed per fragment
- static int const kFragmentSize =
- (kIteratorFragment == IteratorFragment::kWmmaMatrix ? 16 : sizeof(AccessType));
- /// The storage.
- typedef Fragment<Scalar, ShapeCount<Tile>::kCount, kFragmentSize> Storage;
- /// The fragment.
- typedef Fragment<FragmentElement, ShapeCount<Iterations>::kCount * kAccessSize> Fragment;
- /// The fragment iterator.
- typedef FragmentIterator<Fragment, Iterations, AccessType> FragmentIterator;
- /// The fragment const iterator.
- typedef FragmentConstIterator<Fragment, Iterations, AccessType> FragmentConstIterator;
- /// The shape of the fragment.
- typedef typename FragmentIterator::FragmentShape FragmentShape;
-
- /// Default predicate mask type
- typedef PredicateVector<ShapeCount<Iterations>::kCount> PredicateVector;
-
- //
- // Params struct
- //
-
- /// Parameters to the iterator
- struct Params {
- Index stride_d;
- Index stride_h;
- Index stride_w;
-
- Index inc_d;
- Index inc_h;
- Index inc_w;
-
- Index inc_advance;
-
- /// Initializes params
- CUTLASS_HOST_DEVICE
- int initialize(Index _stride_d,
- Index _stride_h,
- Index _stride_w,
- Index _inc_d,
- Index _inc_h,
- Index _inc_w,
- Index _inc_advance) {
- stride_d = _stride_d;
- stride_h = _stride_h;
- stride_w = _stride_w;
-
- inc_d = _inc_d;
- inc_h = _inc_h;
- inc_w = _inc_w;
- inc_advance = _inc_advance;
-
- return 0;
- }
-
- CUTLASS_HOST_DEVICE
- int initialize(Index _stride_d, Index _stride_h, Index _stride_w) {
- stride_d = _stride_d;
- stride_h = _stride_h;
- stride_w = _stride_w;
-
- inc_w = stride_w * Delta::kW;
- inc_h = stride_h * Delta::kH - stride_w * Delta::kW * (Iterations::kW - 1);
-
- if (kAdvance == IteratorAdvance::kH) {
- // Advance in the H dimension.
- inc_d = 0;
- } else if (kAdvance == IteratorAdvance::kW) {
- // Advance in the W dimension.
- inc_d = stride_w * Tile::kW - stride_h * Tile::kH;
- } else {
- // Advance in the D dimension.
- inc_d = stride_d;
- }
-
- inc_advance = 0;
-
- return 0;
- }
-
- CUTLASS_HOST_DEVICE int initialize() {
- stride_d = 0;
- stride_h = 0;
- stride_w = 1;
-
- inc_d = inc_h = inc_w = inc_advance = 0;
-
- return 0;
- }
- };
-
- /// Is the iterator valid?
- CUTLASS_DEVICE bool valid(int d, int h, int w, int c) const { return true; }
-
- //
- // Static function members
- //
-
- /// Initializes a predicate vector
- template <typename PredicateIterator>
- CUTLASS_DEVICE static void initialize_predicates(PredicateIterator predicate_it,
- Coord<3> const &bounds,
- Coord<3> const &offset = make_Coord(0, 0, 0)) {
- for (int d = 0; d < Iterations::kD; ++d) {
- bool enable_d = (d * Delta::kD + offset[0] < bounds[0]);
- for (int h = 0; h < Iterations::kH; ++h) {
- bool enable_h = (h * Delta::kH + offset[1] < bounds[1]);
- for (int w = 0; w < Iterations::kW; ++w) {
- bool enable_w = (w * Tile::kC * Delta::kW + offset[2] < bounds[2]);
- predicate_it.set(d, h, w, 0, enable_d && enable_h && enable_w);
- }
- }
- }
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup tile_load_iterator_concept Tile Load Iterator Concept
-@{
-
-\ref tile_load_iterator_concept enables loading a tile from addressable memory into a fragment
-
-@par Tile Load Iterator Concept
- Types satisfying \ref tile_load_iterator_concept define the following members
- - <b>PredicateVector</b> - a \ref predicate_vector_concept with sufficient predicate storage for
-each access implied by the tile traits
- - <b>Fragment</b> - the destination fragment type satisfying \ref fragment_concept
- - <b>initialize_predicates(pred_it, bounds, block_offset)</b> - function initializing a predicate
-vector according to externally specified bounds
- - <b>load_post_increment(fragment, pred_it)</b> - a method that loads a fragment and increments
-the iterator to the next tile, guarded by a \ref predicate_iterator_concept
- - <b>load_post_increment(fragment)</b> - a method that loads a fragment and increments the
-iterator to the next tile
- - <b>load(fragment, pred_it)</b> - a const method that loads a fragment, guarded by a \ref
-predicate_iterator_concept
- - <b>load(fragment)</b> - a method that loads a fragment
-
-@}
-*/
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief An iterator implementing \ref tile_load_iterator_concept for loading a tile from memory
-* @concept{tile_load_iterator_concept}
-*/
-template <typename Traits_,
- typename Scalar_,
- IteratorAdvance::Kind Advance_ = IteratorAdvance::kH,
- MemorySpace::Kind MemorySpace = MemorySpace::kGeneric,
- typename Index_ = int,
- typename FragmentElement_ = Scalar_,
- IteratorFragment::Kind IteratorFragment_ = IteratorFragment::kScalar,
- typename Skew_ = Shape<0, 0, 0, 0> >
-struct TileLoadIterator : public TileIteratorBase<Traits_,
- Scalar_,
- Advance_,
- MemorySpace,
- Index_,
- FragmentElement_,
- IteratorFragment_,
- Skew_> {
- /// Base class
- typedef TileIteratorBase<Traits_,
- Scalar_,
- Advance_,
- MemorySpace,
- Index_,
- FragmentElement_,
- IteratorFragment_,
- Skew_>
- Base;
-
- /// concept TileTraits
- typedef typename Base::Traits Traits;
-
- /// Scalar element
- typedef typename Base::Scalar Scalar;
-
- /// Fragment element
- typedef typename Base::FragmentElement FragmentElement;
-
- /// Specifies in which dimension post-increment accesses advance.
- static IteratorAdvance::Kind const kAdvance = Base::kAdvance;
-
- /// Specifies type of iterator fragment storage (Salar or WmmaMatrix)
- static IteratorFragment::Kind const kIteratorFragment = Base::kIteratorFragment;
-
- /// Source or destination memory space
- static MemorySpace::Kind const kMemorySpace = Base::kMemorySpace;
-
- /// Index type
- typedef typename Base::Index Index;
-
- /// Skew quantity
- typedef typename Base::Skew Skew;
-
- /// Tile shape
- typedef typename Base::Tile Tile;
-
- /// Delta
- typedef typename Base::Delta Delta;
-
- /// Iterations
- typedef typename Base::Iterations Iterations;
-
- /// ThreadOffset functor
- typedef typename Base::ThreadOffset ThreadOffset;
-
- /// Fragment type
- typedef typename Base::FragmentShape FragmentShape;
-
- /// Memory access type
- typedef typename Base::AccessType AccessType;
-
- /// Fragment definition
- typedef typename Base::Fragment Fragment;
-
- /// Fragment iterator definition
- typedef typename Base::FragmentIterator FragmentIterator;
-
- /// Fragment const iterator definition
- typedef typename Base::FragmentConstIterator FragmentConstIterator;
-
- /// Default predicate mask type
- typedef typename Base::PredicateVector PredicateVector;
-
- /// Storage object that may be loaded from
- typedef typename Base::Storage SharedStorage;
-
- /// IteratorBase parameters
- typedef typename Base::Params BaseParams;
-
- /// Do we require a fence?
- enum { kRequiresLoadFence = Tile::kD == 1 };
-
- /// The pointer type
- typedef Scalar const *Pointer;
-
- /// Parameters
- struct Params : public BaseParams {
- /// Pointer to memory
- Scalar const *pointer;
-
- /// Initialize params to access storage object
- CUTLASS_HOST_DEVICE
- int initialize(SharedStorage const &storage) {
- pointer = &storage[0];
- return 0;
- }
-
- /// Initializes params to access a raw pointer
- CUTLASS_HOST_DEVICE
- int initialize(Scalar const *ptr, Index stride_d, Index stride_h, Index stride_w) {
- Base::Params::initialize(stride_d, stride_h, stride_w);
- pointer = ptr;
- return 0;
- }
-
- /// Initializes params
- CUTLASS_HOST_DEVICE
- int initialize(Scalar const *ptr,
- Index _stride_d,
- Index _stride_h,
- Index _stride_w,
- Index _inc_d,
- Index _inc_h,
- Index _inc_w,
- Index _inc_advance) {
- pointer = ptr;
- Base::Params::initialize(
- _stride_d, _stride_h, _stride_w, _inc_d, _inc_h, _inc_w, _inc_advance);
- return 0;
- }
-
- // Initializes params to default values
- CUTLASS_HOST_DEVICE
- int initialize() { return Base::Params::initialize(); }
- };
-
- //
- // Data members
- //
-
- /// Parameters structure
- Params params;
-
- /// Offset of an individual lane from the start of the tile
- Coord<4> thread_offset;
-
- /// Stage argument enables wrapping after some number of tiles have been loaded.
- int stage;
-
- //
- // Static member functions
- //
-
- /// Initializes a predicate vector
- template <typename PredicateIterator>
- CUTLASS_HOST_DEVICE void initialize_predicates(PredicateIterator predicate_it,
- Coord<3> const &bounds,
- Coord<3> const &block_offset = make_Coord(0,
- 0,
- 0)) {
- Base::initialize_predicates(
- predicate_it,
- bounds,
- block_offset + make_Coord(0, thread_offset[1], thread_offset[2] * Tile::kC));
- }
-
- //
- // Methods
- //
-
- /// Default constructor
- CUTLASS_HOST_DEVICE
- TileLoadIterator() {}
-
- /// Constructs a tile load iterator
- CUTLASS_HOST_DEVICE
- TileLoadIterator(Params const &_params,
- Coord<3> const &block_offset = make_Coord(0, 0, 0),
- ThreadOffset thread_offset_func = ThreadOffset())
- : params(_params), stage(0) {
- thread_offset = thread_offset_func();
-
- Index block_offset_h = 0;
- Index block_offset_w = 0;
- if (kAdvance == IteratorAdvance::kH) {
- block_offset_h = block_offset[1];
- block_offset_w = block_offset[2];
- } else {
- block_offset_h = block_offset[2];
- block_offset_w = block_offset[1];
- }
-
- params.pointer += block_offset[0] * params.stride_d +
- (block_offset_h + thread_offset[1]) * params.stride_h +
- (block_offset_w + thread_offset[2] * Tile::kC) / Tile::kC * params.stride_w;
- }
-
- /// Constructs a tile load iterator
- CUTLASS_HOST_DEVICE
- TileLoadIterator(Params const &,
- SharedStorage &shared_storage,
- Coord<3> const &block_offset = make_Coord(0, 0, 0),
- ThreadOffset thread_offset_func = ThreadOffset())
- : stage(0) {
- int const offset = thread_offset_func()[2];
- params.pointer = &shared_storage[offset];
- }
-
- /// Returns the current pointer
- CUTLASS_HOST_DEVICE
- Scalar const *data() const { return params.pointer; }
-
- /// The accessor.
- CUTLASS_DEVICE void get(AccessType &value, int d, int h, int w, int c) const {
- int const imm =
- ComputeOffsetFromStrides<typename Base::ImmediateOffsetStrides>::get(d, h, w, c);
- Load<Scalar, Base::kAccessSize, kMemorySpace>::load(value, params.pointer, imm);
- }
-
- /// Increment in the D dimension
- CUTLASS_HOST_DEVICE void inc_d() { params.pointer += params.inc_d; }
-
- /// Increment in the H dimension
- CUTLASS_HOST_DEVICE void inc_h() { params.pointer += params.inc_h; }
-
- /// Increment in the W dimension
- CUTLASS_HOST_DEVICE void inc_w() { params.pointer += params.inc_w; }
-
- /// Increment in the next dimension
- CUTLASS_HOST_DEVICE void inc_advance() { params.pointer += params.inc_advance; }
-
- /// Increment the stage.
- CUTLASS_DEVICE void inc_stage() {
- if (Tile::kD > 1) {
- int const kStageSize = Tile::kH * Tile::kW * Tile::kC;
- if (stage == Tile::kD - 1) {
- params.pointer -= (Tile::kD - 1) * kStageSize;
- stage = 0;
- } else {
- params.pointer += kStageSize;
- stage = stage + 1;
- }
- }
- }
-
- public:
- /// Loads a fragment and advances the iterator to the next tile.
- template <typename Fragment, typename PredicateIterator>
- CUTLASS_HOST_DEVICE void load_post_increment(Fragment &fragment, PredicateIterator pred_it) {
- FragmentIterator frag_iterator(fragment);
-
- for (int d = 0; d < Iterations::kD; ++d) {
- for (int h = 0; h < Iterations::kH; ++h) {
- for (int w = 0; w < Iterations::kW; ++w, ++pred_it) {
- if (*pred_it) {
- Load<typename Fragment::Element, Tile::kC, kMemorySpace>::load(
- reinterpret_cast<AccessType &>(frag_iterator.at(d, h, w, 0)), data(), 0);
- }
-
- if (w < Iterations::kW - 1) {
- inc_w();
- }
- }
- if (h < Iterations::kH - 1) {
- inc_h();
- }
- }
- if (d < Iterations::kD - 1) {
- inc_d();
- }
- }
- inc_advance();
- }
-
- /// Loads a fragment and advances the iterator to the next tile.
- template <typename Fragment>
- CUTLASS_HOST_DEVICE void load_post_increment(Fragment &fragment) {
- typename PredicateVector::TrivialIterator pred_it;
- load_post_increment(fragment, pred_it);
- }
-
- /// Loads a fragment without advancing the iterator..
- template <typename Fragment, typename PredicateIterator>
- CUTLASS_HOST_DEVICE void load(Fragment &fragment, PredicateIterator pred_it) const {
- TileLoadIterator _load_it(*this);
- _load_it.load_post_increment(fragment, pred_it);
- }
-
- /// Loads a fragment without advancing the iterator..
- template <typename Fragment>
- CUTLASS_HOST_DEVICE void load(Fragment &fragment) const {
- typename PredicateVector::TrivialIterator pred_it;
- load(fragment, pred_it);
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*!@defgroup tile_store_iterator_concept Tile Store Iterator Concept
-@{
-
-\ref tile_store_iterator_concept enables storing a tile to addressable memory
-
-@par Tile Store Iterator Concept
- Types satisfying \ref tile_load_iterator_concept define the following members
- - <b>PredicateVector</b> - a \ref predicate_vector_concept with sufficient predicate storage for
-each access implied by the tile traits
- - <b>Fragment</b> - the destination fragment type satisfying \ref fragment_concept
- - <b>initialize_predicates(pred_it, bounds, block_offset)</b> - function initializing a predicate
-vector according to externally specified bounds
- - <b>store_post_increment(fragment, pred_it)</b> - a method that stores a fragment and increments
-the iterator to the next tile, guarded by a \ref predicate_iterator_concept
- - <b>store_post_increment(fragment)</b> - a method that stores a fragment and increments the
-iterator to the next tile
- - <b>store(fragment, pred_it)</b> - a const method that stores a fragment, guarded by a \ref
-predicate_iterator_concept
- - <b>store(fragment)</b> - a method that loads a fragment
-
-@}
-*/
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
-* @brief An iterator implementing \ref tile_store_iterator_concept for storing a tile to memory
-* @concept{tile_store_iterator_concept}
-*/
-template <typename Traits_,
- typename Scalar_,
- IteratorAdvance::Kind Advance_ = IteratorAdvance::kH,
- MemorySpace::Kind MemorySpace = MemorySpace::kGeneric,
- typename Index_ = int,
- typename FragmentElement_ = Scalar_,
- IteratorFragment::Kind IteratorFragment_ = IteratorFragment::kScalar,
- typename Skew_ = Shape<0, 0, 0, 0> >
-struct TileStoreIterator : public TileIteratorBase<Traits_,
- Scalar_,
- Advance_,
- MemorySpace,
- Index_,
- FragmentElement_,
- IteratorFragment_,
- Skew_> {
- /// Base class
- typedef TileIteratorBase<Traits_,
- Scalar_,
- Advance_,
- MemorySpace,
- Index_,
- FragmentElement_,
- IteratorFragment_,
- Skew_>
- Base;
-
- /// concept TileTraits
- typedef typename Base::Traits Traits;
-
- /// Scalar element
- typedef typename Base::Scalar Scalar;
-
- /// Fragment element
- typedef typename Base::FragmentElement FragmentElement;
-
- /// Specifies in which dimension post-increment accesses advance.
- static IteratorAdvance::Kind const kAdvance = Base::kAdvance;
-
- /// Specifies type of iterator fragment storage (Salar or WmmaMatrix)
- static IteratorFragment::Kind const kIteratorFragment = Base::kIteratorFragment;
-
- /// Source or destination memory space
- static MemorySpace::Kind const kMemorySpace = Base::kMemorySpace;
-
- /// Index type
- typedef typename Base::Index Index;
-
- /// Skew quantity
- typedef typename Base::Skew Skew;
-
- /// Tile shape
- typedef typename Base::Tile Tile;
-
- /// Delta
- typedef typename Base::Delta Delta;
-
- /// Iterations
- typedef typename Base::Iterations Iterations;
-
- /// ThreadOffset functor
- typedef typename Base::ThreadOffset ThreadOffset;
-
- /// Fragment type
- typedef typename Base::FragmentShape FragmentShape;
-
- /// Memory access type
- typedef typename Base::AccessType AccessType;
-
- /// Fragment definition
- typedef typename Base::Fragment Fragment;
-
- /// Fragment iterator definition
- typedef typename Base::FragmentIterator FragmentIterator;
-
- /// Fragment const iterator definition
- typedef typename Base::FragmentConstIterator FragmentConstIterator;
-
- /// Default predicate mask type
- typedef typename Base::PredicateVector PredicateVector;
-
- /// Storage object which may be stored to
- typedef typename Base::Storage SharedStorage;
-
- /// IteratorBase parameters
- typedef typename Base::Params BaseParams;
-
- /// Parameters
- struct Params : public BaseParams {
- /// Pointer to memory
- Scalar *pointer;
-
- /// Initialize params to access storage object
- CUTLASS_HOST_DEVICE
- int initialize(SharedStorage &storage) {
- pointer = &storage[0];
- return 0;
- }
-
- /// Initializes params to access a raw pointer
- CUTLASS_HOST_DEVICE
- int initialize(Scalar *ptr, Index stride_d, Index stride_h, Index stride_w) {
- Base::Params::initialize(stride_d, stride_h, stride_w);
- pointer = ptr;
- return 0;
- }
-
- /// Initializes params
- CUTLASS_HOST_DEVICE
- int initialize(Scalar *ptr,
- Index _stride_d,
- Index _stride_h,
- Index _stride_w,
- Index _inc_d,
- Index _inc_h,
- Index _inc_w,
- Index _inc_advance) {
- pointer = ptr;
- Base::Params::initialize(
- _stride_d, _stride_h, _stride_w, _inc_d, _inc_h, _inc_w, _inc_advance);
- return 0;
- }
-
- /// Initializes params to default values
- CUTLASS_HOST_DEVICE
- int initialize() { return Base::Params::initialize(); }
- };
-
- //
- // Data members
- //
-
- /// Parameters structure
- Params params;
-
- /// Offset of an individual lane from the start of the tile
- Coord<4> thread_offset;
-
- /// The stage.
- int stage;
-
- //
- // Static member functions
- //
-
- /// Initializes a predicate vector
- template <typename PredicateIterator>
- CUTLASS_HOST_DEVICE void initialize_predicates(PredicateIterator predicate_it,
- Coord<3> const &bounds,
- Coord<3> const &block_offset = make_Coord(0,
- 0,
- 0)) {
- Base::initialize_predicates(
- predicate_it,
- bounds,
- block_offset + make_Coord(0, thread_offset[1], thread_offset[2] * Tile::kC));
- }
-
- //
- // Methods
- //
-
- /// Default constructor
- CUTLASS_HOST_DEVICE
- TileStoreIterator() {}
-
- /// Constructs a tile store iterator
- CUTLASS_HOST_DEVICE
- TileStoreIterator(Params const &_params,
- Coord<3> const &block_offset = make_Coord(0, 0, 0),
- ThreadOffset thread_offset_func = ThreadOffset())
- : params(_params), stage(0) {
- thread_offset = thread_offset_func();
-
- params.pointer += block_offset[0] * params.stride_d +
- (block_offset[1] + thread_offset[1]) * params.stride_h +
- (block_offset[2] + thread_offset[2] * Tile::kC) / Tile::kC * params.stride_w;
- }
-
- /// Constructs a tile store iterator
- CUTLASS_HOST_DEVICE
- TileStoreIterator(Params const &,
- SharedStorage &shared_storage,
- Coord<3> const &block_offset = make_Coord(0, 0, 0),
- ThreadOffset thread_offset_func = ThreadOffset())
- : stage(0) {
- int const offset = thread_offset_func()[2];
- params.pointer = &shared_storage[offset];
- }
-
- /// Returns the current pointer
- CUTLASS_HOST_DEVICE
- Scalar *data() const { return params.pointer; }
-
- /// Increment in the D dimension
- CUTLASS_HOST_DEVICE void inc_d() { params.pointer += params.inc_d; }
-
- /// Increment in the H dimension
- CUTLASS_HOST_DEVICE void inc_h() { params.pointer += params.inc_h; }
-
- /// Increment in the W dimension
- CUTLASS_HOST_DEVICE void inc_w() { params.pointer += params.inc_w; }
-
- /// Increment in the next dimension
- CUTLASS_HOST_DEVICE void inc_advance() {}
-
- /// Increment the stage.
- CUTLASS_DEVICE void inc_stage() {
- if (Tile::kD > 1) {
- int const kStageSize = Tile::kH * Tile::kW * Tile::kC;
- if (stage == Tile::kD - 1) {
- params.pointer -= (Tile::kD - 1) * kStageSize;
- stage = 0;
- } else {
- params.pointer += kStageSize;
- stage = stage + 1;
- }
- }
- }
-
- /// The accessor.
- CUTLASS_DEVICE void set(AccessType const &value, int d, int h, int w, int c) {
- int const imm =
- ComputeOffsetFromStrides<typename Base::ImmediateOffsetStrides>::get(d, h, w, c);
- Store<Scalar, Base::kAccessSize, kMemorySpace>::store(value, params.pointer, imm);
- }
-
- public:
- /// Stores a fragment and advances to the next tile.
- template <typename Fragment, typename PredicateIterator>
- CUTLASS_HOST_DEVICE void store_post_increment(Fragment &fragment, PredicateIterator pred_it) {
- FragmentIterator frag_iterator(fragment);
-
- for (int d = 0; d < Iterations::kD; ++d) {
- for (int h = 0; h < Iterations::kH; ++h) {
- for (int w = 0; w < Iterations::kW; ++w, ++pred_it) {
- if (*pred_it) {
- Store<typename Fragment::Element, Tile::kC, kMemorySpace>::store(
- reinterpret_cast<AccessType &>(frag_iterator.at(d, h, w, 0)), data(), 0);
- }
- if (w < Iterations::kW - 1) {
- inc_w();
- }
- }
- if (h < Iterations::kH - 1) {
- inc_h();
- }
- }
- if (d < Iterations::kD - 1) {
- inc_d();
- }
- }
- inc_advance();
- }
-
- /// Stores a fragment and advances to the next tile.
- template <typename Fragment>
- CUTLASS_HOST_DEVICE void store_post_increment(Fragment &fragment) {
- typename PredicateVector::TrivialIterator pred_it;
- store_post_increment(fragment, pred_it);
- }
-
- /// Stores a fragment without advancing the iterator.
- template <typename Fragment, typename PredicateIterator>
- CUTLASS_HOST_DEVICE void store(Fragment &fragment, PredicateIterator pred_it) const {
- TileStoreIterator _store_it(*this);
- _store_it.store_post_increment(fragment, pred_it);
- }
-
- /// Stores a fragment without advancing the iterator.
- template <typename Fragment>
- CUTLASS_HOST_DEVICE void store(Fragment &fragment) const {
- typename PredicateVector::TrivialIterator pred_it;
- store(fragment, pred_it);
- }
-};
-}
diff --git a/cutlass-example/cutlass/tile_traits_standard.h b/cutlass-example/cutlass/tile_traits_standard.h
deleted file mode 100644
index 14ecd01..0000000
--- a/cutlass-example/cutlass/tile_traits_standard.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines tile traits for several tile partitioning arrangements of threads expected to
- achieve efficient streaming performance.
-*/
-#pragma once
-
-#include <cutlass/tile_iterator.h>
-
-namespace cutlass {
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Basic thread offset function computed from a thread shape
-template <typename ThreadShape>
-struct TiledThreadOffset {
- /// Computes the logical coordinate from thread shape
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- Coord<4> thread_offset;
-
- int index = threadIdx.x;
-
- thread_offset[3] = (index % ThreadShape::kC);
- index = (index / ThreadShape::kC);
-
- thread_offset[2] = (index % ThreadShape::kW);
- index = (index / ThreadShape::kW);
-
- thread_offset[1] = (index % ThreadShape::kH);
- index = (index / ThreadShape::kH);
-
- thread_offset[0] = index;
-
- return thread_offset;
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Tiling in which the number of threads is greater than the
-/// contiguous dimension of the tile.
-template <typename Tile_, int Threads>
-struct TileTraitsStrideMajor {
- /// Shape of tile
- typedef Tile_ Tile;
-
- /// Number of participating threads
- static int const kThreads = Threads;
-
- // Static assertions
- static_assert(!(ShapeCount<Tile>::kDhw % kThreads),
- "Tiling undefined if elements not divisible by threads.");
-
- static_assert(Tile::kW <= kThreads,
- "This specialization assumes there are more threads than the contiguous dimension "
- "of the tile.");
-
- /// Shape of threads
- typedef Shape<1, kThreads / Tile::kW, Tile::kW, 1> ThreadShape;
-
- /// Delta along each dimension
- typedef Shape<1, ThreadShape::kH, 1, 1> Delta;
-
- /// Number of iterations
- typedef Shape<1, Tile::kH / ThreadShape::kH, 1, 1> Iterations;
-
- /// Computes the initial offset
- typedef TiledThreadOffset<ThreadShape> ThreadOffset;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Tiling in which the number of threads is fewer than the tile size
-/// in the contiguous dimension.
-template <typename Tile_, int Threads>
-struct TileTraitsContiguousMajor {
- /// Shape of tile
- typedef Tile_ Tile;
-
- /// Number of participating threads
- static int const kThreads = Threads;
-
- // Static assertions
- static_assert(Tile::kW >= kThreads,
- "This specialization assumes there are more threads than the contiguous dimension "
- "of the tile.");
-
- static_assert(!(ShapeCount<Tile>::kDhw % kThreads),
- "Tiling undefined if elements not divisible by threads.");
-
- static_assert(!(Tile::kW % kThreads),
- "The contiguous size of the tile must be divisible by the number of threads.");
-
- /// Thread shape
- typedef Shape<1, 1, kThreads> ThreadShape;
-
- /// Delta between each thread's access
- typedef Shape<1, 1, kThreads> Delta;
-
- /// Number of iterations
- typedef Shape<1, Tile::kH, Tile::kW / kThreads> Iterations;
-
- /// Computes the initial offset
- typedef TiledThreadOffset<ThreadShape> ThreadOffset;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Tiling in which warps rake across the contiguous dimension
-template <typename Tile_, int Threads>
-struct TileTraitsWarpRake {
- /// Shape of tile
- typedef Tile_ Tile;
-
- /// Number of participating threads
- static int const kThreads = Threads;
-
- /// Hard-coded warp size
- static int const kWarpSize = 32;
-
- /// Number of participating warps
- static int const kWarpCount = kThreads / kWarpSize;
-
- // Static assertions
- static_assert(!(ShapeCount<Tile>::kDhw % kThreads),
- "Tiling undefined if elements not divisible by threads.");
-
- static_assert(!(kThreads % kWarpSize), "Number of threads must be divisible by the warp size.");
-
- static_assert(!(Tile::kW % kWarpSize), "Contiguous dimension must be divisible by the warp size");
-
- /// Warps strip-mined across strided dimension
- static int const kWarpsStrided = __NV_STD_MIN(kWarpCount, Tile::kH);
-
- /// Warps stripmined contiguous dimension
- static int const kWarpsContiguous = kWarpCount / kWarpsStrided;
-
- /// Arrangement of threads
- typedef Shape<1, kWarpsStrided, kWarpsContiguous * kWarpSize> ThreadShape;
-
- /// The same warp rakes along the contiguous dimension
- typedef Shape<1, kWarpsStrided, kWarpSize> Delta;
-
- /// Number of iterations
- typedef Shape<1, Tile::kH / Delta::kH, Tile::kW / ThreadShape::kW> Iterations;
-
- /// Computes the thread offset in (H, W) based on thread ID
- struct ThreadOffset {
- /// Basic thread offset function computed from a thread shape
- CUTLASS_HOST_DEVICE
- Coord<4> operator()() const {
- int tid = threadIdx.x;
- int warp = (tid / kWarpSize);
- int lane = (tid % kWarpSize);
-
- static int const kWarpSpanContiguous = kWarpSize * Iterations::kW;
-
- int warp_w = (warp % kWarpsContiguous);
- int warp_h = (warp / kWarpsContiguous);
-
- return make_Coord(0, warp_h, lane + kWarpSpanContiguous * warp_w, 0);
- }
- };
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Chooses 'best' shape to enable warp raking along contiguous dimension if possible.
-template <typename Tile_, int Threads>
-struct TileTraitsStandard {
- /// Shape of tile
- typedef Tile_ Tile;
-
- /// Number of participating threads
- static int const kThreads = Threads;
-
- /// Hard-coded warp size
- static int const kWarpSize = 32;
-
- /// Number of participating warps
- static int const kWarpCount = kThreads / kWarpSize;
-
- // Static assertions
- static_assert(!(ShapeCount<Tile>::kDhw % kThreads),
- "Tiling undefined if elements not divisible by threads.");
-
- /// Choose the stride-major contiguous tiling if the contiguous dimension is
- /// smaller than the warp size. Otherwise, if it is divisible by the warp size,
- /// choose the warp rake arrangement.
- typedef typename platform::conditional <
- Tile::kW<kWarpSize,
- TileTraitsStrideMajor<Tile, Threads>,
- typename platform::conditional<!(Tile::kW % kWarpSize),
- TileTraitsWarpRake<Tile, Threads>,
- TileTraitsContiguousMajor<Tile, Threads> >::type>::
- type Traits;
-
- /// Delta between accesses
- typedef typename Traits::Delta Delta;
-
- /// Delta between each thread's access
- /// TODO MTA this is wrong for sure, but Delta is used for stride computation at the moment
- typedef Delta ImmediateOffsetStrides;
-
- /// Number of accesses
- typedef typename Traits::Iterations Iterations;
-
- /// Thread offset functor
- typedef typename Traits::ThreadOffset ThreadOffset;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/util/cutlass_math.h b/cutlass-example/cutlass/util/cutlass_math.h
deleted file mode 100644
index 0ecdc43..0000000
--- a/cutlass-example/cutlass/util/cutlass_math.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-
-#pragma once
-
-/**
- * \file
- * \brief Math utilities
- */
-
-#include <cutlass/util/platform.h>
-
-namespace cutlass {
-
-/******************************************************************************
- * Static math utilities
- ******************************************************************************/
-
-/**
- * Statically determine if N is a power-of-two
- */
-template <int N>
-struct is_pow2 : platform::integral_constant<bool, (N & (N - 1)) == 0> {};
-
-/**
- * Statically determine log2(N), rounded down
- */
-template <int N, int CurrentVal = N, int Count = 0>
-struct log2_down {
- /// Static logarithm value
- enum { value = log2_down<N, (CurrentVal >> 1), Count + 1>::value };
-};
-
-// Base case
-template <int N, int Count>
-struct log2_down<N, 1, Count> {
- enum { value = Count };
-};
-
-/**
- * Statically determine log2(N), rounded up
- */
-template <int N, int CurrentVal = N, int Count = 0>
-struct log2_up {
- /// Static logarithm value
- enum { value = log2_up<N, (CurrentVal >> 1), Count + 1>::value };
-};
-
-// Base case
-template <int N, int Count>
-struct log2_up<N, 1, Count> {
- enum { value = ((1 << Count) < N) ? Count + 1 : Count };
-};
-
-/**
- * Statically estimate sqrt(N) to the nearest power-of-two
- */
-template <int N>
-struct sqrt_est {
- enum { value = 1 << (log2_up<N>::value / 2) };
-};
-
-/**
- * For performing a constant-division with a compile-time assertion that the
- * Divisor evenly-divides the Dividend.
- */
-template <int Dividend, int Divisor>
-struct divide_assert {
- enum { value = Dividend / Divisor };
-
- static_assert((Dividend % Divisor == 0), "Not an even multiple");
-};
-
-/******************************************************************************
- * Rounding
- ******************************************************************************/
-
-/**
- * Round dividend up to the nearest multiple of divisor
- */
-template <typename dividend_t, typename divisor_t>
-CUTLASS_HOST_DEVICE dividend_t round_nearest(dividend_t dividend, divisor_t divisor) {
- return ((dividend + divisor - 1) / divisor) * divisor;
-}
-
-/**
- * Greatest common divisor
- */
-template <typename value_t>
-CUTLASS_HOST_DEVICE value_t gcd(value_t a, value_t b) {
- for (;;) {
- if (a == 0) return b;
- b %= a;
- if (b == 0) return a;
- a %= b;
- }
-}
-
-/**
- * Least common multiple
- */
-template <typename value_t>
-CUTLASS_HOST_DEVICE value_t lcm(value_t a, value_t b) {
- value_t temp = gcd(a, b);
-
- return temp ? (a / temp * b) : 0;
-}
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/util/debug.h b/cutlass-example/cutlass/util/debug.h
deleted file mode 100644
index 6055e3f..0000000
--- a/cutlass-example/cutlass/util/debug.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-
-#pragma once
-
-/**
- * \file
- * \brief Debugging and logging functionality
- */
-
-#include <stdio.h>
-
-namespace cutlass {
-
-/******************************************************************************
- * Debug and logging macros
- ******************************************************************************/
-
-/**
- * Formats and prints the given message to stdout
- */
-#if !defined(CUDA_LOG)
-#if !defined(__CUDA_ARCH__)
-#define CUDA_LOG(format, ...) printf(format, __VA_ARGS__)
-#else
-#define CUDA_LOG(format, ...) \
- printf("[block (%d,%d,%d), thread (%d,%d,%d)]: " format, \
- blockIdx.x, \
- blockIdx.y, \
- blockIdx.z, \
- threadIdx.x, \
- threadIdx.y, \
- threadIdx.z, \
- __VA_ARGS__);
-#endif
-#endif
-
-/**
- * Formats and prints the given message to stdout only if DEBUG is defined
- */
-#if !defined(CUDA_LOG_DEBUG)
-#ifdef DEBUG
-#define CUDA_LOG_DEBUG(format, ...) CUDA_LOG(format, __VA_ARGS__)
-#else
-#define CUDA_LOG_DEBUG(format, ...)
-#endif
-#endif
-
-/**
- * \brief The corresponding error message is printed to \p stderr (or \p stdout in device code)
- * along with the supplied source context.
- *
- * \return The CUDA error.
- */
-__host__ CUTLASS_DEVICE cudaError_t cuda_perror_impl(cudaError_t error,
- const char* filename,
- int line) {
- (void)filename;
- (void)line;
- if (error) {
-#if !defined(__CUDA_ARCH__)
- fprintf(
- stderr, "CUDA error %d [%s, %d]: %s\n", error, filename, line, cudaGetErrorString(error));
- fflush(stderr);
-#else
- printf("CUDA error %d [%s, %d]\n", error, filename, line);
-#endif
- }
- return error;
-}
-
-/**
- * \brief Perror macro
- */
-#ifndef CUDA_PERROR
-#define CUDA_PERROR(e) cuda_perror_impl((cudaError_t)(e), __FILE__, __LINE__)
-#endif
-
-/**
- * \brief Perror macro with exit
- */
-#ifndef CUDA_PERROR_EXIT
-#define CUDA_PERROR_EXIT(e) \
- if (cuda_perror_impl((cudaError_t)(e), __FILE__, __LINE__)) { \
- exit(1); \
- }
-#endif
-
-/**
- * \brief Perror macro only if DEBUG is defined
- */
-#ifndef CUDA_PERROR_DEBUG
-#ifdef DEBUG
-#define CUDA_PERROR_DEBUG(e) CUDA_PERROR(e)
-#else
-#define CUDA_PERROR_DEBUG(e) (e)
-#endif
-#endif
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/util/platform.h b/cutlass-example/cutlass/util/platform.h
deleted file mode 100644
index 2a44c10..0000000
--- a/cutlass-example/cutlass/util/platform.h
+++ /dev/null
@@ -1,801 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-
-#pragma once
-
-/**
- * \file
- * \brief C++ features that may be otherwise unimplemented for CUDA device functions.
- *
- * This file has three components:
- *
- * (1) Macros:
- * - Empty macro defines for C++ keywords not supported by the current
- * version of C++. These simply allow compilation to proceed (but do
- * not provide the added semantics).
- * - \p noexcept
- * - \p constexpr
- * - \p nullptr
- * - \p static_assert
- *
- * - Macro functions that we need in constant expressions because the
- * C++ equivalents require constexpr compiler support. These are
- * prefixed with \p __NV_STD_*
- * - \p __NV_STD_MAX
- * - \p __NV_STD_MIN
- *
- * (2) Re-implementations of STL functions and types:
- * - C++ features that need the \p __device__ annotation. These are
- * placed into the \p platform namespace.
- * - \p plus
- * - \p less
- * - \p greater
- * - \p min
- * - \p max
- * - \p methods on std::pair (==, !=, <, <=, >, >=, and make_pair())
- *
- * (3) Stop-gap implementations of unsupported STL functions and types:
- * - STL functions and types defined by C++ 11/14/17/etc. that are not
- * provided by the current version of C++. These are placed into the
- * \p platform namespace
- * - \p integral_constant
- * - \p nullptr_t
- * - \p true_type
- * - \p false_type
- * - \p bool_constant
- * - \p enable_if
- * - \p conditional
- * - \p is_same
- * - \p is_base_of
- * - \p remove_const
- * - \p remove_volatile
- * - \p remove_cv
- * - \p is_volatile
- * - \p is_pointer
- * - \p is_void
- * - \p is_integral
- * - \p is_floating_point
- * - \p is_arithmetic
- * - \p is_fundamental
- * - \p is_trivially_copyable
- * - \p alignment_of
- * - \p aligned_storage
- *
- * (4) Functions and types that are STL-like (but aren't in the STL):
- * - \p TODO: min and max functors?
- *
- * The idea is that, as we drop support for older compilers, we can simply #define
- * the \p __NV_STD_XYZ macros and \p platform namespace to alias their C++
- * counterparts (or trivially find-and-replace their occurrences in code text).
- */
-
-//-----------------------------------------------------------------------------
-// Dependencies
-//-----------------------------------------------------------------------------
-
-#include <stdint.h>
-
-#if !defined(__CUDACC_RTC__)
-//-----------------------------------------------------------------------------
-// Include STL files that platform provides functionality for
-//-----------------------------------------------------------------------------
-
-#include <algorithm> // Minimum/maximum operations
-#include <cstddef> // nullptr_t
-#include <functional> // Arithmetic operations
-#include <utility> // For methods on std::pair
-#if (!defined(_MSC_VER) && (__cplusplus >= 201103L)) || (defined(_MSC_VER) && (_MS_VER >= 1500))
-#include <type_traits> // For integral constants, conditional metaprogramming, and type traits
-#endif
-
-#include <cutlass/cutlass.h>
-
-#endif
-/******************************************************************************
- * Macros
- ******************************************************************************/
-//-----------------------------------------------------------------------------
-// Keywords
-//-----------------------------------------------------------------------------
-
-/// noexcept, constexpr
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1900))
-#ifndef noexcept
-#define noexcept
-#endif
-#ifndef constexpr
-#define constexpr
-#endif
-#endif
-
-/// nullptr
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1310))
-#ifndef nullptr
-#define nullptr 0
-#endif
-#endif
-
-/// static_assert
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1600))
-#ifndef static_assert
-#define __platform_cat_(a, b) a##b
-#define __platform_cat(a, b) __platform_cat_(a, b)
-#define static_assert(__e, __m) typedef int __platform_cat(AsSeRt, __LINE__)[(__e) ? 1 : -1]
-#endif
-#endif
-
-//-----------------------------------------------------------------------------
-// Functions
-//-----------------------------------------------------------------------------
-
-/// Select maximum(a, b)
-#ifndef __NV_STD_MAX
-#define __NV_STD_MAX(a, b) (((b) > (a)) ? (b) : (a))
-#endif
-
-/// Select minimum(a, b)
-#ifndef __NV_STD_MIN
-#define __NV_STD_MIN(a, b) (((b) < (a)) ? (b) : (a))
-#endif
-
-/******************************************************************************
- * Re-implementations
- ******************************************************************************/
-namespace cutlass {
-namespace platform {
-
-//-----------------------------------------------------------------------------
-// Arithmetic operations, comparisons <functional>
-//-----------------------------------------------------------------------------
-
-/// platform::plus
-template <typename T>
-struct plus {
- CUTLASS_HOST_DEVICE constexpr T operator()(const T& lhs, const T& rhs) const { return lhs + rhs; }
-};
-
-/// std::less
-template <typename T>
-struct less {
- CUTLASS_HOST_DEVICE constexpr bool operator()(const T& lhs, const T& rhs) const {
- return lhs < rhs;
- }
-};
-
-/// std::greater
-template <typename T>
-struct greater {
- CUTLASS_HOST_DEVICE constexpr bool operator()(const T& lhs, const T& rhs) const {
- return lhs > rhs;
- }
-};
-
-//-----------------------------------------------------------------------------
-// Minimum/maximum operations <algorithm>
-//-----------------------------------------------------------------------------
-
-/// std::min
-template <typename T>
-CUTLASS_HOST_DEVICE constexpr const T& min(const T& a, const T& b) {
- return (b < a) ? b : a;
-}
-
-/// std::max
-template <typename T>
-CUTLASS_HOST_DEVICE constexpr const T& max(const T& a, const T& b) {
- return (a < b) ? b : a;
-}
-
-#if !defined(__CUDACC_RTC__)
-//-----------------------------------------------------------------------------
-// Methods on std::pair
-//-----------------------------------------------------------------------------
-
-using std::pair;
-
-template <class T1, class T2>
-CUTLASS_HOST_DEVICE constexpr bool operator==(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) {
- return (lhs.first == rhs.first) && (lhs.second == rhs.second);
-}
-
-template <class T1, class T2>
-CUTLASS_HOST_DEVICE constexpr bool operator!=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) {
- return (lhs.first != rhs.first) && (lhs.second != rhs.second);
-}
-
-template <class T1, class T2>
-CUTLASS_HOST_DEVICE constexpr bool operator<(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) {
- return (lhs.first < rhs.first) ? true : (rhs.first < lhs.first) ? false
- : (lhs.second < rhs.second);
-}
-
-template <class T1, class T2>
-CUTLASS_HOST_DEVICE constexpr bool operator<=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) {
- return !(rhs < lhs);
-}
-
-template <class T1, class T2>
-CUTLASS_HOST_DEVICE constexpr bool operator>(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) {
- return (rhs < lhs);
-}
-
-template <class T1, class T2>
-CUTLASS_HOST_DEVICE constexpr bool operator>=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) {
- return !(lhs < rhs);
-}
-
-template <class T1, class T2>
-CUTLASS_HOST_DEVICE std::pair<T1, T2> make_pair(T1 t, T2 u) {
- std::pair<T1, T2> retval;
- retval.first = t;
- retval.second = u;
- return retval;
-}
-#endif
-
-} // namespace platform
-
-/******************************************************************************
- * Implementations of C++ 11/14/17/... STL features
- ******************************************************************************/
-
-namespace platform {
-
-//-----------------------------------------------------------------------------
-// Integral constant helper types <type_traits>
-//-----------------------------------------------------------------------------
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1500))
-
-/// std::integral_constant
-template <typename value_t, value_t V>
-struct integral_constant;
-
-/// std::integral_constant
-template <typename value_t, value_t V>
-struct integral_constant {
- static const value_t value = V;
-
- typedef value_t value_type;
- typedef integral_constant<value_t, V> type;
-
- CUTLASS_HOST_DEVICE operator value_type() const { return value; }
-
- CUTLASS_HOST_DEVICE const value_type operator()() const { return value; }
-};
-
-#else
-
-using std::integral_constant;
-using std::pair;
-
-#endif
-
-/// The type used as a compile-time boolean with true value.
-typedef integral_constant<bool, true> true_type;
-
-/// The type used as a compile-time boolean with false value.
-typedef integral_constant<bool, false> false_type;
-
-#if (!defined(_MSC_VER) && (__cplusplus <= 201402L)) || (defined(_MSC_VER) && (_MSC_VER < 1900))
-
-/// std::bool_constant
-template <bool V>
-struct bool_constant : platform::integral_constant<bool, V> {};
-
-#else
-
-using std::bool_constant;
-
-#endif
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1700))
-
-/// std::nullptr_t
-struct nullptr_t {};
-
-#else
-
-using std::nullptr_t;
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Conditional metaprogramming <type_traits>
-//-----------------------------------------------------------------------------
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1600))
-
-/// std::enable_if (true specialization)
-template <bool C, typename T = void>
-struct enable_if {
- typedef T type;
-};
-
-/// std::enable_if (false specialization)
-template <typename T>
-struct enable_if<false, T> {};
-
-/// std::conditional (true specialization)
-template <bool B, class T, class F>
-struct conditional {
- typedef T type;
-};
-
-/// std::conditional (false specialization)
-template <class T, class F>
-struct conditional<false, T, F> {
- typedef F type;
-};
-
-#else
-
-using std::enable_if;
-using std::conditional;
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Const/volatility specifiers <type_traits>
-//-----------------------------------------------------------------------------
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1500))
-
-/// std::remove_const (non-const specialization)
-template <typename T>
-struct remove_const {
- typedef T type;
-};
-
-/// std::remove_const (const specialization)
-template <typename T>
-struct remove_const<const T> {
- typedef T type;
-};
-
-/// std::remove_volatile (non-volatile specialization)
-template <typename T>
-struct remove_volatile {
- typedef T type;
-};
-
-/// std::remove_volatile (volatile specialization)
-template <typename T>
-struct remove_volatile<volatile T> {
- typedef T type;
-};
-
-/// std::remove_cv
-template <typename T>
-struct remove_cv {
- typedef typename remove_volatile<typename remove_const<T>::type>::type type;
-};
-
-#else
-
-using std::remove_const;
-using std::remove_volatile;
-using std::remove_cv;
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Type relationships <type_traits>
-//-----------------------------------------------------------------------------
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1500))
-
-/// std::is_same (false specialization)
-template <typename A, typename B>
-struct is_same : false_type {};
-
-/// std::is_same (true specialization)
-template <typename A>
-struct is_same<A, A> : true_type {};
-
-/// Helper for std::is_base_of
-template <typename BaseT, typename DerivedT>
-struct is_base_of_helper {
- typedef char (&yes)[1];
- typedef char (&no)[2];
-
- template <typename B, typename D>
- struct dummy {
- CUTLASS_HOST_DEVICE operator B*() const;
- CUTLASS_HOST_DEVICE operator D*();
- };
-
- template <typename T>
- CUTLASS_HOST_DEVICE static yes check(DerivedT*, T);
-
- CUTLASS_HOST_DEVICE static no check(BaseT*, int);
-
- static const bool value = sizeof(check(dummy<BaseT, DerivedT>(), int())) == sizeof(yes);
-};
-
-/// std::is_base_of
-template <typename BaseT, typename DerivedT>
-struct is_base_of
- : integral_constant<bool,
- (is_base_of_helper<typename remove_cv<BaseT>::type,
- typename remove_cv<DerivedT>::type>::value) ||
- (is_same<typename remove_cv<BaseT>::type,
- typename remove_cv<DerivedT>::type>::value)> {};
-
-#else
-
-using std::is_same;
-using std::is_base_of;
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Type properties <type_traits>
-//-----------------------------------------------------------------------------
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1500))
-
-/// std::is_volatile
-template <typename T>
-struct is_volatile : false_type {};
-template <typename T>
-struct is_volatile<volatile T> : true_type {};
-
-/// Helper for std::is_pointer (false specialization)
-template <typename T>
-struct is_pointer_helper : false_type {};
-
-/// Helper for std::is_pointer (true specialization)
-template <typename T>
-struct is_pointer_helper<T*> : true_type {};
-
-/// std::is_pointer
-template <typename T>
-struct is_pointer : is_pointer_helper<typename remove_cv<T>::type> {};
-
-/// std::is_void
-template <typename T>
-struct is_void : is_same<void, typename remove_cv<T>::type> {};
-
-/// std::is_integral
-template <typename T>
-struct is_integral : false_type {};
-template <>
-struct is_integral<char> : true_type {};
-template <>
-struct is_integral<signed char> : true_type {};
-template <>
-struct is_integral<unsigned char> : true_type {};
-template <>
-struct is_integral<short> : true_type {};
-template <>
-struct is_integral<unsigned short> : true_type {};
-template <>
-struct is_integral<int> : true_type {};
-template <>
-struct is_integral<unsigned int> : true_type {};
-template <>
-struct is_integral<long> : true_type {};
-template <>
-struct is_integral<unsigned long> : true_type {};
-template <>
-struct is_integral<long long> : true_type {};
-template <>
-struct is_integral<unsigned long long> : true_type {};
-template <typename T>
-struct is_integral<volatile T> : is_integral<T> {};
-template <typename T>
-struct is_integral<const T> : is_integral<T> {};
-template <typename T>
-struct is_integral<const volatile T> : is_integral<T> {};
-
-/// std::is_floating_point
-template <typename T>
-struct is_floating_point
- : integral_constant<bool,
- (is_same<float, typename remove_cv<T>::type>::value ||
- is_same<double, typename remove_cv<T>::type>::value)> {};
-
-/// std::is_arithmetic
-template <typename T>
-struct is_arithmetic
- : integral_constant<bool, (is_integral<T>::value || is_floating_point<T>::value)> {};
-
-/// std::is_fundamental
-template <typename T>
-struct is_fundamental
- : integral_constant<bool,
- (is_arithmetic<T>::value || is_void<T>::value ||
- is_same<nullptr_t, typename remove_cv<T>::type>::value)> {};
-
-#else
-
-using std::is_volatile;
-using std::is_pointer;
-using std::is_void;
-using std::is_integral;
-using std::is_floating_point;
-using std::is_arithmetic;
-using std::is_fundamental;
-
-#endif
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1800)) || \
- (defined(__GNUG__) && (__GNUC__ < 5))
-
-/**
- * std::is_trivially_copyable
- *
- * This implementation only evaluates true if T is fundamental or pointer
- *
- * Without help from partial template specializations provided by the user for
- * a specific class or struct, this trait will never report that the specified
- * class or struct is trivially-copyable ; this is always safe,
- * if possibly sub-optimal.
- */
-template <typename T>
-struct is_trivially_copyable
- : integral_constant<bool, (is_fundamental<T>::value || is_pointer<T>::value)> {};
-
-#else
-
-using std::is_trivially_copyable;
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Alignment and layout utilities
-//-----------------------------------------------------------------------------
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1500))
-
-/// std::alignment_of
-template <typename value_t>
-struct alignment_of {
- struct pad {
- value_t val;
- char byte;
- };
-
- enum { value = sizeof(pad) - sizeof(value_t) };
-};
-
-#else
-
-template <typename value_t>
-struct alignment_of : std::alignment_of<value_t> {};
-
-#endif
-
-/* 16B specializations where 32-bit Win32 host compiler disagrees with device compiler */
-template <>
-struct alignment_of<int4> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<uint4> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<float4> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<long4> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<ulong4> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<longlong2> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<ulonglong2> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<double2> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<longlong4> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<ulonglong4> {
- enum { value = 16 };
-};
-template <>
-struct alignment_of<double4> {
- enum { value = 16 };
-};
-
-// Specializations for volatile/const qualified types
-template <typename value_t>
-struct alignment_of<volatile value_t> : alignment_of<value_t> {};
-template <typename value_t>
-struct alignment_of<const value_t> : alignment_of<value_t> {};
-template <typename value_t>
-struct alignment_of<const volatile value_t> : alignment_of<value_t> {};
-
-#if (!defined(_MSC_VER) && (__cplusplus < 201103L)) || (defined(_MSC_VER) && (_MSC_VER < 1800))
-
-template <size_t Align>
-struct aligned_chunk;
-template <>
-struct __align__(1) aligned_chunk<1> {
- uint8_t buff;
-};
-template <>
-struct __align__(2) aligned_chunk<2> {
- uint16_t buff;
-};
-template <>
-struct __align__(4) aligned_chunk<4> {
- uint32_t buff;
-};
-template <>
-struct __align__(8) aligned_chunk<8> {
- uint32_t buff[2];
-};
-template <>
-struct __align__(16) aligned_chunk<16> {
- uint32_t buff[4];
-};
-template <>
-struct __align__(32) aligned_chunk<32> {
- uint32_t buff[8];
-};
-template <>
-struct __align__(64) aligned_chunk<64> {
- uint32_t buff[16];
-};
-template <>
-struct __align__(128) aligned_chunk<128> {
- uint32_t buff[32];
-};
-template <>
-struct __align__(256) aligned_chunk<256> {
- uint32_t buff[64];
-};
-template <>
-struct __align__(512) aligned_chunk<512> {
- uint32_t buff[128];
-};
-template <>
-struct __align__(1024) aligned_chunk<1024> {
- uint32_t buff[256];
-};
-template <>
-struct __align__(2048) aligned_chunk<2048> {
- uint32_t buff[512];
-};
-template <>
-struct __align__(4096) aligned_chunk<4096> {
- uint32_t buff[1024];
-};
-
-/// std::aligned_storage
-template <size_t Len, size_t Align>
-struct aligned_storage {
- typedef aligned_chunk<Align> type[Len / sizeof(aligned_chunk<Align>)];
-};
-
-#else
-
-using std::aligned_storage;
-
-#endif
-
-#if !defined(__CUDACC_RTC__)
-/// Default deleter
-template <typename T>
-struct default_delete {
- void operator()(T* ptr) const { delete ptr; }
-};
-
-/// Partial specialization for deleting array types
-template <typename T>
-struct default_delete<T[]> {
- void operator()(T* ptr) const { delete[] ptr; }
-};
-
-/// std::unique_ptr
-template <class T, class Deleter = default_delete<T> >
-class unique_ptr {
- public:
- typedef T* pointer;
- typedef T element_type;
- typedef Deleter deleter_type;
-
- private:
- /// Pointer to memory
- pointer _ptr;
-
- /// Deleter
- deleter_type _deleter;
-
- public:
- unique_ptr() : _ptr(nullptr) {}
- unique_ptr(pointer p) : _ptr(p) {}
-
- ~unique_ptr() {
- if (_ptr) {
- _deleter(_ptr);
- }
- }
- /// Returns a pointer to the managed object or nullptr if no object is owned.
- pointer get() const noexcept { return _ptr; }
-
- /// Releases ownership of the managed object, if any
- pointer release() noexcept {
- pointer p(_ptr);
- _ptr = nullptr;
- return p;
- }
-
- /// Replaces the managed object, deleting the old object.
- void reset(pointer p = pointer()) noexcept {
- pointer old_ptr = _ptr;
- _ptr = p;
- if (old_ptr != nullptr) {
- get_deleter()(old_ptr);
- }
- }
-
- /// Swaps the managed objects with *this and another unique_ptr
- void swap(unique_ptr& other) noexcept { std::swap(_ptr, other._ptr); }
-
- /// Returns the deleter object
- Deleter& get_deleter() noexcept { return _deleter; }
-
- /// Returns the deleter object
- Deleter const& get_deleter() const noexcept { return _deleter; }
-
- /// Checks whether an object is owned
- operator bool() const noexcept { return _ptr != nullptr; }
-
- /// Dereferences the unique_ptr
- T& operator*() const { return *_ptr; }
-
- /// Returns a pointer to the managed object
- pointer operator->() const noexcept { return _ptr; }
-
- /// Array access to managed object
- T& operator[](size_t i) const { return _ptr[i]; }
-};
-
-/// Specializes the swap algorithm
-template <typename T, typename Deleter>
-void swap(unique_ptr<T, Deleter>& lhs, unique_ptr<T, Deleter>& rhs) noexcept {
- lhs.swap(rhs);
-}
-#endif
-
-}; // namespace platform
-}; // namespace cutlass
diff --git a/cutlass-example/cutlass/vector.h b/cutlass-example/cutlass/vector.h
deleted file mode 100644
index a66dfde..0000000
--- a/cutlass-example/cutlass/vector.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Defines a 1D vector of elements held in the registers of each thread.
-*/
-#pragma once
-
-#if !defined(__CUDACC_RTC__) || defined(CUTLASS_NVRTC_HAS_FP16)
-#include <cuda_fp16.h>
-#endif
-
-#include <cutlass/util/platform.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <size_t kAlignment_>
-struct AlignedStruct {};
-
-template <>
-struct __align__(1) AlignedStruct<1>{};
-template <>
-struct __align__(2) AlignedStruct<2>{};
-template <>
-struct __align__(4) AlignedStruct<4>{};
-template <>
-struct __align__(8) AlignedStruct<8>{};
-template <>
-struct __align__(16) AlignedStruct<16>{};
-template <>
-struct __align__(32) AlignedStruct<32>{};
-template <>
-struct __align__(64) AlignedStruct<64>{};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int kLanes_>
-union Vector {
- /// The scalar type.
- typedef Scalar_ Scalar;
-
- /// The number of elements in the vector.
- enum { kLanes = kLanes_ };
- /// The size of the vector.
- enum { kVectorSize = kLanes * (int)sizeof(Scalar) };
- /// The number of registers needed to store the vector.
- enum { kRegisters = kVectorSize < 4 ? 1 : kVectorSize / 4 };
-
- // Make sure that the vector type makes sense.
- static_assert(kVectorSize <= 16, "Vector type is too large");
-
- /// The aligned storage to make sure we have good alignment.
- AlignedStruct<kVectorSize> aligned_;
- /// The associated array of scalars.
- Scalar scalars[kLanes];
- /// The data in registers.
- uint32_t registers[kRegisters];
-
- /// Accessor to the ith lane.
- CUTLASS_DEVICE Scalar const& operator[](uint32_t i) const { return scalars[i]; }
- /// Accessor to the ith lane.
- CUTLASS_DEVICE Scalar& operator[](uint32_t i) { return scalars[i]; }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#if !defined(__CUDACC_RTC__) || defined(CUTLASS_NVRTC_HAS_FP16)
-
-template <int kLanes_>
-union Vector<half, kLanes_> {
- /// The scalar type.
- typedef half Scalar;
-
- /// The number of elements in the vector.
- enum { kLanes = kLanes_ };
- /// The size of the vector.
- enum { kVectorSize = kLanes * (int)sizeof(Scalar) };
- /// The number of registers needed to store the vector.
- enum { kRegisters = kVectorSize < 4 ? 1 : kVectorSize / 4 };
-
- // Make sure that the vector type makes sense.
- static_assert(kVectorSize <= size_t(16), "Vector type is too large");
-
- /// The aligned storage to make sure we have good alignment.
- AlignedStruct<kVectorSize> aligned_;
- /// The associated array of scalars.
- uint16_t scalars[kLanes];
- /// The data in registers.
- uint32_t registers[kRegisters];
-
- /// Accessor to the ith lane.
- CUTLASS_DEVICE Scalar const& operator[](uint32_t i) const {
- return reinterpret_cast<Scalar const&>(scalars[i]);
- }
- /// Accessor to the ith lane.
- CUTLASS_DEVICE Scalar& operator[](uint32_t i) { return reinterpret_cast<Scalar&>(scalars[i]); }
-};
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_>
-CUTLASS_DEVICE void make_zero(Scalar_& x) {
- x = Scalar_(0);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Element_, int kLanes_ = 1>
-struct Vectorize {
- typedef Vector<Element_, kLanes_> Type;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Element_>
-struct Vectorize<Element_, 1> {
- typedef Element_ Type;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename Scalar_, int kLanes_>
-CUTLASS_DEVICE void make_zero(Vector<Scalar_, kLanes_>& vec) {
- for (int i = 0; i < Vector<Scalar_, kLanes_>::kRegisters; ++i) {
- vec.registers[i] = 0;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// cutlass::Extent similar to std::extent but applicable to CUTLASS types
-//
-
-/// Returns the extent of a scalar or vector
-template <typename T>
-struct Extent {
- static size_t const kValue = 1;
-};
-
-/// Returns the number of lanes of a vector if need be
-template <typename T, int Lanes>
-struct Extent<Vector<T, Lanes> > {
- static size_t const kValue = Lanes;
-};
-
-/// Returns the number of lanes of a vector if need be
-template <typename T, int Lanes>
-struct Extent<Vector<T, Lanes> const> {
- static size_t const kValue = Lanes;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Traits describing properties of vectors and scalar-as-vectors
-template <typename T>
-struct VectorTraits {
- /// Scalar type
- typedef T Scalar;
-
- /// Number of lanes of vector
- static int const kLanes = 1;
-
- /// True if the type is actually a cutlass::Vector, otherwise false
- static bool const IsVector = false;
-
- /// Type that is always a vector
- typedef Vector<T, 1> Vector;
-};
-
-/// Partial specialization for actual cutlass::Vector
-template <typename T, int Lanes>
-struct VectorTraits<Vector<T, Lanes> > {
- /// Scalar type
- typedef T Scalar;
-
- /// Number of lanes of vector
- static int const kLanes = Lanes;
-
- /// Type is actually a cutlass::Vector
- static bool const IsVector = true;
-
- /// Type that is always a Vector
- typedef Vector<T, Lanes> Vector;
-};
-
-/// Partial specialization for actual cutlass::Vector
-template <typename T, int Lanes>
-struct VectorTraits<Vector<T, Lanes> const> {
- /// Scalar type
- typedef T Scalar;
-
- /// Number of lanes of vector
- static int const kLanes = Lanes;
-
- /// Type is actually a cutlass::Vector
- static bool const IsVector = true;
-
- /// Type that is always a Vector
- typedef Vector<T, Lanes> Vector;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/cutlass/wmma_matrix.h b/cutlass-example/cutlass/wmma_matrix.h
deleted file mode 100644
index c4d8a0b..0000000
--- a/cutlass-example/cutlass/wmma_matrix.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Abstractions for loading and storing matrices using the CUDA WMMA API.
-*/
-#pragma once
-
-#if defined(__CUDACC__) && (!defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 700)
-
-// Dependent header files should use the following macro to guard all code using
-// nvcuda::wmma:: to enable compilation for CUDA Compute Capabilities < sm_70.
-// Earlier shader models not support Tensor Cores.
-#define CUTLASS_USE_WMMA_API
-
-#include "stdio.h"
-
-#include <crt/mma.h>
-#include <cutlass/fragment.h>
-#include <cutlass/load_store.h>
-#include <cutlass/matrix_traits.h>
-#include <cutlass/shape.h>
-#include <cutlass/vector.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Statically maps cutlass::MatrixLayout => nvcuda::wmma layout tags
-template <MatrixLayout::Kind kLayout_>
-struct WmmaLayout {
- typedef nvcuda::wmma::col_major Layout;
-};
-
-/// Statically maps cutlass::MatrixLayout => nvcuda::wmma layout tags
-template <>
-struct WmmaLayout<MatrixLayout::kRowMajor> {
- typedef nvcuda::wmma::row_major Layout;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Adapter to nvcuda::wmma fragment load and store operations
-template <GemmOperand::Kind kOperand_,
- MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename WmmaShape_>
-struct WmmaMatrix {};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Adapter to nvcuda::wmma fragment accessors for A operand
-template <MatrixLayout::Kind kLayout_, typename Scalar_, typename WmmaShape_>
-struct WmmaMatrix<GemmOperand::kA, kLayout_, Scalar_, WmmaShape_>
- : public nvcuda::wmma::fragment<
- /// The nvcuda::wmma operand name.
- nvcuda::wmma::matrix_a,
- /// The dimensions.
- WmmaShape_::kW,
- WmmaShape_::kH,
- WmmaShape_::kD,
- /// The scalar.
- Scalar_,
- /// The layout.
- typename WmmaLayout<kLayout_>::Layout> {
- /// This type.
- typedef WmmaMatrix<GemmOperand::kA, kLayout_, Scalar_, WmmaShape_> This_;
-
- /// Fill-in the element.
- CUTLASS_DEVICE This_& operator=(Scalar_ const& x) {
- nvcuda::wmma::fill_fragment(*this, x);
- return *this;
- }
-
- /// Load from memory.
- CUTLASS_DEVICE void load(Scalar_ const* pointer, int const stride) {
- nvcuda::wmma::load_matrix_sync(*this, pointer, stride);
- }
-
- /// Store to memory.
- CUTLASS_DEVICE void store(Scalar_* pointer, int const stride) const {
- nvcuda::wmma::store_matrix_sync(pointer, *this, stride);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Adapter to nvcuda::wmma fragment accessors for B operand
-template <MatrixLayout::Kind kLayout_, typename Scalar_, typename WmmaShape_>
-struct WmmaMatrix<GemmOperand::kB, kLayout_, Scalar_, WmmaShape_>
- : public nvcuda::wmma::fragment<
- /// The nvcuda::wmma operand name.
- nvcuda::wmma::matrix_b,
- /// The dimensions.
- WmmaShape_::kW,
- WmmaShape_::kH,
- WmmaShape_::kD,
- /// The scalar.
- Scalar_,
- /// The layout.
- typename WmmaLayout<kLayout_>::Layout> {
- /// This type.
- typedef WmmaMatrix<GemmOperand::kB, kLayout_, Scalar_, WmmaShape_> This_;
-
- /// Fill-in the element.
- CUTLASS_DEVICE This_& operator=(Scalar_ const& x) {
- nvcuda::wmma::fill_fragment(*this, x);
- return *this;
- }
-
- /// Load from memory.
- CUTLASS_DEVICE void load(Scalar_ const* pointer, int const stride) {
- nvcuda::wmma::load_matrix_sync(*this, pointer, stride);
- }
-
- /// Store to memory.
- CUTLASS_DEVICE void store(Scalar_* pointer, int const stride) const {
- nvcuda::wmma::store_matrix_sync(pointer, *this, stride);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Adapter to nvcuda::wmma fragment accessors for C operand
-template <MatrixLayout::Kind kLayout_, typename Scalar_, typename WmmaShape_>
-struct WmmaMatrix<GemmOperand::kC, kLayout_, Scalar_, WmmaShape_>
- : public nvcuda::wmma::fragment<
- /// The nvcuda::wmma operand name.
- nvcuda::wmma::accumulator,
- /// The dimensions.
- WmmaShape_::kW,
- WmmaShape_::kH,
- WmmaShape_::kD,
- /// The scalar.
- Scalar_> {
- /// This type.
- typedef WmmaMatrix<GemmOperand::kC, kLayout_, Scalar_, WmmaShape_> This_;
- /// The layout.
- static MatrixLayout::Kind const kLayout = kLayout_;
-
- /// Fill-in the element.
- CUTLASS_DEVICE This_& operator=(Scalar_ const& x) {
- nvcuda::wmma::fill_fragment(*this, x);
- return *this;
- }
-
- /// Load from memory.
- CUTLASS_DEVICE void load(Scalar_ const* pointer, int const stride) {
- bool const kIsRowMajor = kLayout == MatrixLayout::kRowMajor;
- nvcuda::wmma::load_matrix_sync(
- *this,
- pointer,
- stride,
- kIsRowMajor ? nvcuda::wmma::mem_row_major : nvcuda::wmma::mem_col_major);
- }
-
- /// Store to memory.
- CUTLASS_DEVICE void store(Scalar_* pointer, int const stride) const {
- bool const kIsRowMajor = kLayout == MatrixLayout::kRowMajor;
- nvcuda::wmma::store_matrix_sync(
- pointer,
- *this,
- stride,
- kIsRowMajor ? nvcuda::wmma::mem_row_major : nvcuda::wmma::mem_col_major);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
-
-#endif // defined CUTLASS_USE_WMMA_API
diff --git a/cutlass-example/cutlass_example.cu b/cutlass-example/cutlass_example.cu
deleted file mode 100644
index 0e5722c..0000000
--- a/cutlass-example/cutlass_example.cu
+++ /dev/null
@@ -1,355 +0,0 @@
-//added by me
-#include <cutlass/wmma_matrix.h>
-#include <cutlass/gemm/gemm.h>
-#include <cutlass/gemm/wmma_gemm_traits.h>
-#include <gemm_testbed.h>
-#include <gemm.h>
-
-int main(int argc, char* argv[]) {
-
-#ifdef WMMA_GEMM_16x16x16_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(16, 16, 16);
-#endif
-
-#ifdef WMMA_GEMM_16x16x32_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(16, 16, 32);
-#endif
-
-#ifdef WMMA_GEMM_16x16x16_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(16, 16, 16);
-#endif
-
-
-#ifdef WMMA_GEMM_16x16x32_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(16, 16, 32);
-#endif
-
-#ifdef WMMA_GEMM_16x16x16_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(16, 16, 16);
-#endif
-
-#ifdef WMMA_GEMM_16x16x32_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(16, 16, 32);
-#endif
-
-#ifdef WMMA_GEMM_16x16x16_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(16, 16, 16);
-#endif
-
-#ifdef WMMA_GEMM_16x16x32_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(16, 16, 32);
-#endif
-
-#ifdef WMMA_GEMM_32x32x32_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(32, 32, 32);
-#endif
-#ifdef WMMA_GEMM_32x32x32_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(32, 32, 32);
-#endif
-#ifdef WMMA_GEMM_32x32x32_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(32, 32, 32);
-#endif
-#ifdef WMMA_GEMM_32x32x32_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(32, 32, 32);
-#endif
-
-#ifdef WMMA_GEMM_128x128x128_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(128, 128, 128);
-#endif
-#ifdef WMMA_GEMM_128x128x128_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(128, 128, 128);
-#endif
-#ifdef WMMA_GEMM_128x128x128_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(128, 128, 128);
-#endif
-#ifdef WMMA_GEMM_128x128x128_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 16, 16> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(128, 128, 128);
-#endif
-
-#ifdef WMMA_16x16x16_GEMM_256x256x128_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(256, 256, 128);
-#endif
-
-#ifdef WMMA_16x16x16_GEMM_256x256x128_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(256, 256, 128);
-#endif
-
-#ifdef WMMA_16x16x16_GEMM_256x256x128_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<32, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(256, 256, 128);
-#endif
-
-#ifdef WMMA_16x16x16_GEMM_256x256x128_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<32, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(256, 256, 128);
-#endif
-
-#ifdef WMMA_GEMM_256x256x256_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(256, 256, 256);
-#endif
-
-#ifdef WMMA_GEMM_256x256x256_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(256, 256, 256);
-#endif
-
-#ifdef WMMA_GEMM_256x256x256_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(256, 256, 256);
-#endif
-
-#ifdef WMMA_GEMM_256x256x256_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(256, 256, 256);
-#endif
-#ifdef WMMA_GEMM_512x512x512_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(512, 512, 512);
-#endif
-
-#ifdef WMMA_GEMM_512x512x512_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(512, 512, 512);
-#endif
-
-#ifdef WMMA_GEMM_512x512x512_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(512, 512, 512);
-#endif
-
-#ifdef WMMA_GEMM_512x512x512_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(512, 512, 512);
-#endif
-
-#ifdef WMMA_GEMM_768x768x768_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(768, 768, 768);
-#endif
-#ifdef WMMA_GEMM_768x768x768_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(768, 768, 768);
-#endif
-
-#ifdef WMMA_GEMM_768x768x768_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(768, 768, 768);
-#endif
-
-#ifdef WMMA_GEMM_768x768x768_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(768, 768, 768);
-#endif
-
-
-#ifdef WMMA_GEMM_1024x1024x1024_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(1024, 1024, 1024);
-#endif
-
-#ifdef WMMA_GEMM_1024x1024x1024_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(1024, 1024, 1024);
-#endif
-
-#ifdef WMMA_GEMM_1024x1024x1024_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(1024, 1024, 1024);
-#endif
-
-#ifdef WMMA_GEMM_1024x1024x1024_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(1024, 1024, 1024);
-#endif
-#ifdef WMMA_GEMM_2048x2048x2048_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(2048, 2048, 2048);
-#endif
-
-#ifdef WMMA_GEMM_2048x2048x2048_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(2048, 2048, 2048);
-#endif
-
-#ifdef WMMA_GEMM_2048x2048x2048_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(2048, 2048, 2048);
-#endif
-
-#ifdef WMMA_GEMM_2048x2048x2048_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(2048, 2048, 2048);
-#endif
-#ifdef WMMA_GEMM_4096x4096x4096_NT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(4096, 4096, 4096);
-#endif
-
-#ifdef WMMA_GEMM_4096x4096x4096_NN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kColumnMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(4096, 4096, 4096);
-#endif
-
-#ifdef WMMA_GEMM_4096x4096x4096_TT
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kRowMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(4096, 4096, 4096);
-#endif
-
-#ifdef WMMA_GEMM_4096x4096x4096_TN
- typedef cutlass::gemm::WmmaGemmTraits<cutlass::MatrixLayout::kRowMajor,
- cutlass::MatrixLayout::kColumnMajor,
- cutlass::Shape<64, 128, 128> >
- WmmaGemmTraits;
- run_gemm<WmmaGemmTraits>(4096, 4096, 4096);
-#endif
-}
-
-
diff --git a/cutlass-example/device_memory.h b/cutlass-example/device_memory.h
deleted file mode 100644
index ab561d8..0000000
--- a/cutlass-example/device_memory.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are not permitted.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************/
-
-#pragma once
-
-/**
- * \file
- * \brief C++ interface to CUDA device memory management functions.
- */
-
-#include <memory>
-
-#include <cutlass/util/debug.h>
-#include <cutlass/util/platform.h>
-#include <exceptions.h>
-
-namespace cutlass {
-namespace device_memory {
-
-/******************************************************************************
- * Allocation lifetime
- ******************************************************************************/
-
-/// Allocate a buffer of \p count elements of type \p T on the current CUDA device
-template <typename T>
-T* allocate(size_t count = 1) {
- T* ptr = 0;
- size_t bytes = sizeof(T) * count;
-
- cudaError_t cuda_error = CUDA_PERROR(cudaMalloc((void**)&ptr, bytes));
- if (cuda_error != cudaSuccess) {
- throw cuda_exception("Failed to allocate memory", cuda_error);
- }
-
- return ptr;
-}
-
-/// Free the buffer pointed to by \p ptr
-template <typename T>
-void free(T* ptr) {
- if (ptr) {
- cudaError_t cuda_error = CUDA_PERROR(cudaFree(ptr));
- if (cuda_error != cudaSuccess) {
- throw cuda_exception("Failed to free device memory", cuda_error);
- }
- }
-}
-
-/******************************************************************************
- * Data movement
- ******************************************************************************/
-
-template <typename T>
-void copy(T* dst, T const* src, size_t count, cudaMemcpyKind kind) {
- size_t bytes = count * sizeof(T);
-
- cudaError_t cuda_error = CUDA_PERROR(cudaMemcpy(dst, src, bytes, kind));
- if (cuda_error != cudaSuccess) {
- throw cuda_exception("cudaMemcpy() failed", cuda_error);
- }
-}
-
-template <typename T>
-void copy_to_device(T* dst, T const* src, size_t count = 1) {
- copy(dst, src, count, cudaMemcpyHostToDevice);
-}
-
-template <typename T>
-void copy_to_host(T* dst, T const* src, size_t count = 1) {
- copy(dst, src, count, cudaMemcpyDeviceToHost);
-}
-
-template <typename T>
-void copy_device_to_device(T* dst, T const* src, size_t count = 1) {
- copy(dst, src, count, cudaMemcpyDeviceToDevice);
-}
-
-/// Copies elements from device memory to host-side range
-template <typename OutputIterator, typename T>
-void insert_to_host(OutputIterator begin, OutputIterator end, T const* device_begin) {
- size_t elements = end - begin;
- copy_to_host(&*begin, device_begin, elements);
-}
-
-/// Copies elements to device memory from host-side range
-template <typename T, typename InputIterator>
-void insert_to_device(T* device_begin, InputIterator begin, InputIterator end) {
- size_t elements = end - begin;
- copy_to_device(device_begin, &*begin, elements);
-}
-
-/******************************************************************************
- * "Smart" device memory allocation
- ******************************************************************************/
-
-/// Device allocation abstraction that tracks size and capacity
-template <typename T>
-struct allocation {
- /// Delete functor for CUDA device memory
- struct deleter {
- void operator()(T* ptr) {
- cudaError_t cuda_error = CUDA_PERROR(cudaFree(ptr));
- if (cuda_error != cudaSuccess) {
- // noexcept
- // throw cuda_exception("cudaFree() failed", cuda_error);
- return;
- }
- }
- };
-
- /// Number of elements of T allocated on the current CUDA device
- size_t capacity;
-
- /// Smart pointer
- platform::unique_ptr<T, deleter> smart_ptr;
-
- //
- //
- //
-
- /// Constructor: allocates no memory
- allocation() : capacity(0) {}
-
- /// Constructor: allocates \p capacity elements on the current CUDA device
- allocation(size_t _capacity) : smart_ptr(allocate<T>(_capacity)), capacity(_capacity) {}
-
- /// Destructor
- ~allocation() { reset(); }
-
- /// Returns a pointer to the managed object
- T* get() const { return smart_ptr.get(); }
-
- /// Releases the ownership of the managed object (without deleting) and resets capacity to zero
- T* release() {
- capacity = 0;
- return smart_ptr.release();
- }
-
- /// Deletes the managed object and resets capacity to zero
- void reset() {
- capacity = 0;
- smart_ptr.reset();
- }
-
- /// Deletes managed object, if owned, and replaces its reference with a given pointer and capacity
- void reset(T* _ptr, size_t _capacity) {
- smart_ptr.reset(_ptr);
- capacity = _capacity;
- }
-
- /// Returns a pointer to the object owned by *this
- T* operator->() const { return smart_ptr.get(); }
-
- /// Returns the deleter object which would be used for destruction of the managed object.
- deleter& get_deleter() { return smart_ptr.get_deleter(); }
-
- /// Returns the deleter object which would be used for destruction of the managed object (const)
- const deleter& get_deleter() const { return smart_ptr.get_deleter(); }
-};
-
-} // namespace device_memory
-} // namespace cutlass
diff --git a/cutlass-example/exceptions.h b/cutlass-example/exceptions.h
deleted file mode 100644
index 72d99fe..0000000
--- a/cutlass-example/exceptions.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are not permitted.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************/
-
-#pragma once
-
-/**
- * \file
- * \brief C++ exception semantics for CUDA error codes
- */
-
-#include <cuda_runtime.h>
-#include <iosfwd>
-#include <stdexcept>
-
-#include <cutlass/util/platform.h>
-
-namespace cutlass {
-
-/// C++ exception wrapper for CUDA \p cudaError_t
-class cuda_exception : public std::exception {
- public:
- /// Constructor
- cuda_exception(const char* msg = "", cudaError_t err = cudaErrorUnknown) : msg(msg), err(err) {}
-
- /// Returns the underlying CUDA \p cudaError_t
- cudaError_t cudaError() const { return err; }
-
- protected:
- /// Explanatory string
- const char* msg;
-
- /// Underlying CUDA \p cudaError_t
- cudaError_t err;
-};
-
-/// Writes a cudaError_t to an output stream
-inline std::ostream& operator<<(std::ostream& out, cudaError_t result) {
- return out << cudaGetErrorString(result);
-}
-
-/// Writes a cuda_exception instance to an output stream
-inline std::ostream& operator<<(std::ostream& out, cuda_exception const& e) {
- return out << e.what() << ": " << e.cudaError();
-}
-
-} // namespace cutlass
diff --git a/cutlass-example/executionFlow b/cutlass-example/executionFlow
deleted file mode 100644
index 356afed..0000000
--- a/cutlass-example/executionFlow
+++ /dev/null
@@ -1,262 +0,0 @@
-mov.b64%rd33, _ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE_param_0;
-mov.u64 %rd1, %rd33;
-ld.param.u64 %rd34, [_ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE_param_0+48];
-cvta.to.global.u64 %rd2, %rd34;
-mov.u32 %r301, %ctaid.x;
-shl.b32 %r1, %r301, 4;
-ld.param.u64 %rd36, [_ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE_param_0+136];
-cvta.to.global.u64 %rd4, %rd36;
-mov.u32 %r302, %ctaid.y;
-shl.b32 %r2, %r302, 4;
-mov.u32 %r3, %tid.x;
-shr.u32 %r4, %r3, 1;
-and.b32 %r303, %r3, 1;
-shl.b32 %r5, %r303, 3;
-add.s32 %r6, %r5, %r1;
-ld.param.u32 %r7, [_ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE_param_0+20];
-mad.lo.s32 %r304, %r7, %r4, %r6;
-cvt.s64.s32%rd5, %r304;
-mul.wide.s32 %rd37, %r304, 2;
-add.s64 %rd6, %rd2, %rd37;
-ld.param.u32 %r8, [_ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE_param_0];
-sub.s32 %r305, %r8, %r6;
-ld.param.u32 %r9, [_ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE_param_0+8];
-setp.gt.s32%p2, %r9, 0;
-setp.gt.s32%p3, %r305, 0;
-and.pred %p4, %p3, %p2;
-selp.u32%r306, 1, 0, %p4;
-setp.gt.s32%p5, %r9, 16;
-and.pred %p6, %p3, %p5;
-selp.u16%rs1, 1, 0, %p6;
-mul.wide.u16 %r10, %rs1, 2;
-selp.u32%r307, -1, 0, %p6;
-bfi.b32 %r481, %r307, %r306, 1, 1;
-bfe.u32 %r308, %r3, 1, 4;
-mad.lo.s32 %r12, %r308, 24, %r5;
-setp.lt.s32%p7, %r12, 768;
-@%p7 bra BB0_2;
-ld.param.u32 %r310, [%rd1+4];
-ld.param.u32 %r13, [%rd1+108];
-add.s32 %r16, %r5, %r2;
-mad.lo.s32 %r311, %r13, %r4, %r16;
-cvt.s64.s32%rd7, %r311;
-mul.wide.s32 %rd45, %r311, 2;
-add.s64 %rd8, %rd4, %rd45;
-sub.s32 %r312, %r310, %r16;
-setp.gt.s32%p9, %r312, 0;
-and.pred %p11, %p9, %p2;
-selp.u32%r313, 1, 0, %p11;
-and.pred %p13, %p9, %p5;
-selp.u16%rs2, 1, 0, %p13;
-mul.wide.u16 %r17, %rs2, 2;
-selp.u32%r314, -1, 0, %p13;
-bfi.b32 %r480, %r314, %r313, 1, 1;
-@%p7 bra BB0_4;
-setp.lt.s32%p14, %r9, 32;
-@%p14 bra BB0_7;
-setp.lt.s32%p18, %r4, %r9;
-selp.b32%r321, %r481, %r10, %p18;
-add.s32 %r322, %r4, 16;
-setp.lt.s32%p19, %r322, %r9;
-and.b32 %r323, %r321, 1;
-selp.b32%r481, %r321, %r323, %p19;
-selp.b32%r324, %r480, %r17, %p18;
-and.b32 %r325, %r324, 1;
-selp.b32%r480, %r324, %r325, %p19;
-bra.uni BB0_8;
-and.b32 %r330, %r481, 1;
-setp.eq.b32%p20, %r330, 1;
-mov.u32 %r571, 0;
-mov.u32 %r559, %r571;
-mov.u32 %r560, %r571;
-mov.u32 %r561, %r571;
-mov.u32 %r562, %r571;
-@!%p20 bra BB0_10;
-bra.uni BB0_9;
-ld.global.v4.u32 {%r561, %r562, %r559, %r560}, [%rd6];
-ld.param.u32 %r33, [%rd1+32];
-cvt.s64.s32%rd53, %r33;
-add.s64 %rd9, %rd5, %rd53;
-shl.b64 %rd54, %rd9, 1;
-add.s64 %rd10, %rd2, %rd54;
-and.b32 %r339, %r481, 2;
-setp.eq.s32%p21, %r339, 0;
-mov.u32 %r563, %r571;
-mov.u32 %r564, %r571;
-mov.u32 %r565, %r571;
-mov.u32 %r566, %r571;
-@%p21 bra BB0_12;
-and.b32 %r348, %r480, 1;
-setp.eq.b32%p22, %r348, 1;
-mov.u32 %r567, %r571;
-mov.u32 %r568, %r571;
-mov.u32 %r569, %r571;
-mov.u32 %r570, %r571;
-@!%p22 bra BB0_14;
-bra.uni BB0_13;
-ld.global.v4.u32 {%r569, %r570, %r567, %r568}, [%rd8];
-ld.param.u32 %r50, [%rd1+120];
-cvt.s64.s32%rd55, %r50;
-add.s64 %rd56, %rd7, %rd55;
-shl.b64 %rd57, %rd56, 1;
-add.s64 %rd11, %rd4, %rd57;
-and.b32 %r357, %r480, 2;
-setp.eq.s32%p23, %r357, 0;
-mov.u32 %r572, %r571;
-mov.u32 %r573, %r571;
-mov.u32 %r574, %r571;
-@%p23 bra BB0_16;
-shl.b32 %r362, %r12, 1;
-mov.u32 %r363, _ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE$__cuda_local_var_29658_57_non_const_shared_storage;
-add.s32 %r59, %r363, %r362;
-st.shared.v4.u32 [%r59], {%r561, %r562, %r559, %r560};
-st.shared.v4.u32 [%r59+768], {%r565, %r566, %r563, %r564};
-st.shared.v4.u32 [%r59+1536], {%r569, %r570, %r567, %r568};
-st.shared.v4.u32 [%r59+2304], {%r573, %r574, %r571, %r572};
-bar.sync 0;
-shr.u32 %r60, %r3, 5;
-shl.b32 %r61, %r60, 4;
-setp.lt.u32%p24, %r61, 768;
-@%p24 bra BB0_18;
-mul.wide.s32 %rd65, %r61, 2;
-cvt.u64.u32 %temp, %r363;
-cvta.shared.u64 %rd66, %temp;
-add.s64 %rd67, %rd66, %rd65;
-add.s64 %rd12, %rd67, 1536;
-mov.u32 %r374, 24;
-wmma.load.a.sync.col.m16n16k16.f16 {%r590, %r589, %r588, %r587, %r586, %r585, %r584, %r583}, [%rd66], %r374;
-wmma.load.b.sync.row.m16n16k16.f16 {%r582, %r581, %r580, %r579, %r578, %r577, %r576, %r575}, [%rd12], %r374;
-add.s32 %r599, %r9, -32;
-mov.u32 %r609, 0;
-setp.lt.s32%p25, %r599, 1;
-@%p25 bra BB0_19;
-mov.u32 %r610, %r609;
-mov.u32 %r611, %r609;
-mov.u32 %r612, %r609;
-mov.u32 %r613, %r609;
-mov.u32 %r614, %r609;
-mov.u32 %r615, %r609;
-mov.u32 %r616, %r609;
-setp.lt.s32%p34, %r599, -31;
-@%p34 bra BB0_35;
-mov.u32 %r477, %tid.x;
-shr.u32 %r476, %r477, 5;
-shl.b32 %r475, %r476, 4;
-add.s32 %r434, %r475, 384;
-mul.wide.s32 %rd96, %r434, 2;
-add.s64 %rd97, %rd66, %rd96;
-add.s64 %rd26, %rd97, 1536;
-add.s64 %rd99, %rd66, 768;
-wmma.load.a.sync.col.m16n16k16.f16 {%r257, %r256, %r255, %r254, %r250, %r251, %r253, %r252}, [%rd99], %r374;
-wmma.load.b.sync.row.m16n16k16.f16 {%r265, %r264, %r263, %r262, %r258, %r259, %r261, %r260}, [%rd26], %r374;
-mov.b32 %f63, %r615;
-mov.b32 %f64, %r616;
-mov.b32 %f65, %r613;
-mov.b32 %f66, %r614;
-mov.b32 %f67, %r611;
-mov.b32 %f68, %r612;
-mov.b32 %f69, %r609;
-mov.b32 %f70, %r610;
-wmma.mma.sync.col.row.m16n16k16.f32.f32 {%f10, %f11, %f12, %f13, %f14, %f15, %f16, %f17}, {%r590, %r589, %r588, %r587, %r586, %r585, %r584, %r583}, {%r582, %r581, %r580, %r579, %r578, %r577, %r576, %r575}, {%f70, %f69, %f68, %f67, %f66, %f65, %f64, %f63};
-bar.sync 0;
-bar.sync 0;
-wmma.mma.sync.col.row.m16n16k16.f32.f32 {%f71, %f72, %f73, %f74, %f75, %f76, %f77, %f78}, {%r257, %r256, %r255, %r254, %r250, %r251, %r253, %r252}, {%r265, %r264, %r263, %r262, %r258, %r259, %r261, %r260}, {%f10, %f11, %f12, %f13, %f14, %f15, %f16, %f17};
-mov.b32 %r610, %f71;
-mov.b32 %r609, %f72;
-mov.b32 %r612, %f73;
-mov.b32 %r611, %f74;
-mov.b32 %r614, %f75;
-mov.b32 %r613, %f76;
-mov.b32 %r616, %f77;
-mov.b32 %r615, %f78;
-add.s32 %r599, %r599, -32;
-setp.gt.s32%p35, %r599, -32;
-@%p35 bra BB0_34;
-mov.b64%rd145, _ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE_param_0;
-mov.u64 %rd144, %rd145;
-mov.u32 %r472, %tid.x;
-ld.param.f32 %f145, [%rd144+428];
-ld.param.u32 %r471, [%rd144+324];
-shr.u32 %r470, %r472, 5;
-ld.param.u32 %r469, [%rd144+332];
-mov.u32 %r468, %ctaid.x;
-shl.b32 %r467, %r468, 4;
-mov.u32 %r466, _ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE$__cuda_local_var_29658_57_non_const_shared_storage;
-mov.u32 %r465, %ctaid.y;
-shl.b32 %r464, %r465, 4;
-ld.param.v2.u32 {%r438, %r439}, [%rd144+288];
-ld.param.u32 %r284, [%rd144+300];
-ld.param.u32 %r440, [%rd144+320];
-ld.param.u32 %r285, [%rd144+336];
-ld.param.f32 %f18, [%rd144+424];
-ld.param.u32 %r287, [%rd144+304];
-ld.param.u64 %rd100, [%rd144+312];
-cvta.to.global.u64 %rd101, %rd100;
-and.b32 %r441, %r472, 3;
-shl.b32 %r288, %r441, 2;
-shr.u32 %r289, %r472, 2;
-add.s32 %r290, %r289, %r464;
-add.s32 %r291, %r288, %r467;
-mad.lo.s32 %r442, %r290, %r440, %r291;
-cvt.s64.s32%rd102, %r442;
-mul.wide.s32 %rd103, %r442, 4;
-add.s64 %rd27, %rd101, %rd103;
-sub.s32 %r292, %r469, %r290;
-shl.b32 %r293, %r470, 8;
-shl.b32 %r443, %r289, 4;
-add.s32 %r294, %r443, %r288;
-shl.b32 %r444, %r294, 2;
-add.s32 %r295, %r466, %r444;
-cvt.s64.s32%rd104, %r471;
-add.s64 %rd105, %rd102, %rd104;
-shl.b64 %rd106, %rd105, 2;
-add.s64 %rd28, %rd101, %rd106;
-setp.eq.f32%p36, %f145, 0f00000000;
-@%p36 bra BB0_48;
-setp.lt.s32%p51, %r293, 256;
-@%p51 bra BB0_50;
-setp.lt.s32%p52, %r294, 256;
-@%p52 bra BB0_52;
-ld.param.u32 %r474, [_ZN7cutlass4gemm11gemm_kernelINS0_4GemmINS0_14WmmaGemmTraitsILNS_12MatrixLayout4KindE1ELS5_0ENS_5ShapeILi32ELi16ELi16ELi1EEEfNS0_13LinearScalingIfNS0_19FragmentMultiplyAddIfEEEEfS7_NS6_ILi16ELi16ELi16ELi1EEELi8ELi8EiNS0_20WmmaGemmTraitsHelperILS5_1ELS5_0ES7_ffSB_S7_SC_Li8ELi8EiEEEEEEEEvNT_6ParamsE_param_0];
-mul.wide.s32 %rd142, %r293, 4;
-add.s64 %rd32, %rd66, %rd142;
-setp.lt.s32%p1, %r291, %r474;
-bar.sync 0;
-mov.b32 %f121, %r610;
-mov.b32 %f122, %r609;
-mov.b32 %f123, %r612;
-mov.b32 %f124, %r611;
-mov.b32 %f125, %r614;
-mov.b32 %f126, %r613;
-mov.b32 %f127, %r616;
-mov.b32 %f128, %r615;
-mov.u32 %r458, 16;
-wmma.store.d.sync.col.m16n16k16.f32 [%rd32], {%f121, %f122, %f123, %f124, %f125, %f126, %f127, %f128}, %r458;
-bar.sync 0;
-ld.shared.v4.u32 {%r459, %r460, %r461, %r462}, [%r295+512];
-setp.gt.s32%p53, %r292, 0;
-and.pred %p54, %p1, %p53;
-@!%p54 bra BB0_54;
-bra.uni BB0_53;
-ld.shared.v4.f32 {%f129, %f130, %f131, %f132}, [%r295];
-mul.f32 %f137, %f18, %f132;
-mul.f32 %f138, %f18, %f131;
-mul.f32 %f139, %f18, %f130;
-mul.f32 %f140, %f18, %f129;
-st.global.v4.f32 [%rd27], {%f140, %f139, %f138, %f137};
-mov.b32 %f141, %r459;
-mul.f32 %f43, %f18, %f141;
-mov.b32 %f142, %r460;
-mul.f32 %f44, %f18, %f142;
-mov.b32 %f143, %r461;
-mul.f32 %f45, %f18, %f143;
-mov.b32 %f144, %r462;
-mul.f32 %f46, %f18, %f144;
-sub.s32 %r463, %r292, %r285;
-setp.gt.s32%p56, %r463, 0;
-and.pred %p57, %p1, %p56;
-@!%p57 bra BB0_56;
-bra.uni BB0_55;
-st.global.v4.f32 [%rd28], {%f43, %f44, %f45, %f46};
-bra.uni BB0_56;
-ret;
diff --git a/cutlass-example/gemm.h b/cutlass-example/gemm.h
deleted file mode 100644
index 18dfdf6..0000000
--- a/cutlass-example/gemm.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/***************************************************************************************************
-* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright notice, this list of
-* conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright notice, this list of
-* conditions and the following disclaimer in the documentation and/or other materials
-* provided with the distribution.
-* * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
-* to endorse or promote products derived from this software without specific prior written
-* permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
-* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-**************************************************************************************************/
-
-#include <cutlass/cutlass.h>
-#include <gemm_testbed.h>
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmTraits_>
-static void run_gemm(
- int m,
- int n,
- int k,
- int lda,
- int ldb,
- int ldc,
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type alpha =
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type(1),
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type beta =
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type(0)) {
- typedef cutlass::gemm::Gemm<GemmTraits_> Gemm;
- typename Gemm::Params params;
-
- printf("run_gemm-2:m=%d\n",m);
- printf("run_gemm-2:n=%d\n",n);
- printf("run_gemm-2:k=%d\n",k);
- printf("run_gemm-2:lda=%d\n",lda);
- printf("run_gemm-2:ldb=%d\n",ldb);
- printf("run_gemm-2:ldc=%d\n",ldc);
- printf("run_gemm-2:alpha=%.2f\n",alpha);
- printf("run_gemm-2:beta=%.2f\n",beta);
-
- test::GemmTestbed<
- typename test::GemmTestbedTraits<
- typename GemmTraits_::GemmConfig::ScalarA>::host_type, // AType
- typename test::GemmTestbedTraits<
- typename GemmTraits_::GemmConfig::ScalarB>::host_type, // BType
- typename test::GemmTestbedTraits<
- typename GemmTraits_::Epilogue::ScalarC>::host_type, // CType
- typename test::GemmTestbedTraits<
- typename GemmTraits_::Epilogue::Accumulators::Element>::host_type, // Accumulator
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type // Scalar
- >
- testbed(m,
- n,
- k,
- lda,
- ldb,
- ldc,
- cutlass::convert(GemmTraits_::kLayoutA),
- cutlass::convert(GemmTraits_::kLayoutB),
- alpha,
- beta);
-
- testbed.initialize();
-
- // if (testbed.has_cublas_support()) {
- // EXPECT_TRUE(testbed.verify_host_with_cublas());
- // }
-
- params.initialize(testbed.M(),
- testbed.N(),
- testbed.K(),
- testbed.alpha,
- testbed.ptr_A(),
- testbed.lda(),
- testbed.ptr_B(),
- testbed.ldb(),
- testbed.beta,
- testbed.ptr_C_initial(),
- testbed.ldc(),
- testbed.ptr_computed(),
- testbed.ldc());
-
- printf("SIZE_OF_PARAM=%lu\n",sizeof(params));
- void *ptr =&params;
- for(int kk=0;kk<108;kk++){
- printf("KERNELPARAM:%d:%08x\n",kk,*((((int *) ptr)+kk)));
- }
- printf("m=%lu\n",sizeof(params.m));
- printf("n=%lu\n",sizeof(params.n));
- printf("k=%lu\n",sizeof(params.k));
-// printf("alpha=%d\n",sizeof(params.alpha));
-// printf("beta=%d\n",sizeof(params.beta));
-// printf("d_a=%d\n",sizeof(params.d_a));
-// printf("lda=%d\n",sizeof(params.lda));
-// printf("d_b=%d\n",sizeof(params.d_b));
-// printf("ldb=%d\n",sizeof(params.ldb));
-// printf("d_c=%d\n",sizeof(params.d_c));
-// printf("ldc=%d\n",sizeof(params.ldc));
-// printf("d_d=%d\n",sizeof(params.d_d));
-// printf("ldd=%d\n",sizeof(params.ldd));
- Gemm::launch(params);
-
- cudaError_t result = cudaDeviceSynchronize();
- if(result==cudaSuccess){
- printf("Successfully Launched\n");
- }
- int save=1;
- int myval=testbed.verify_with_host(save,save);
- if(myval==1){
- printf("Result Verified\n");
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename GemmTraits_>
-static void run_gemm(
- int m,
- int n,
- int k,
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type alpha =
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type(1),
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type beta =
- typename test::GemmTestbedTraits<typename GemmTraits_::Epilogue::Scalar>::host_type(0)) {
- int lda = GemmTraits_::kLayoutA == cutlass::MatrixLayout::kColumnMajor ? m : k;
- int ldb = GemmTraits_::kLayoutB == cutlass::MatrixLayout::kColumnMajor ? k : n;
- printf("run_gemm-1:m=%d\n",m);
- printf("run_gemm-1:n=%d\n",n);
- printf("run_gemm-1:k=%d\n",k);
- printf("run_gemm-1:alpha=%.2f\n",alpha);
- printf("run_gemm-1:beta=%.2f\n",beta);
- printf("run_gemm-1:lda=%d\n",lda);
- printf("run_gemm-1:ldb=%d\n",ldb);
- run_gemm<GemmTraits_>(m, n, k, lda, ldb, m, alpha, beta);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/cutlass-example/gemm_testbed.h b/cutlass-example/gemm_testbed.h
deleted file mode 100644
index 97409b1..0000000
--- a/cutlass-example/gemm_testbed.h
+++ /dev/null
@@ -1,462 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Test environment for GEMM
-*/
-
-#pragma once
-
-#include <fstream>
-#include <iomanip>
-#include <sstream>
-#include <string>
-
-#include <cutlass/matrix_traits.h>
-#include <cutlass/util/platform.h>
-
-#include <host_tensor.h>
-#include <tensor_view_io.h>
-#include <type_traits.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <cutlass::GemmOperand::Kind kOperand_,
- cutlass::MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename WmmaShape_>
-struct WmmaMatrix;
-}
-
-namespace test {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-struct GemmTestbedTraits : public cutlass::TypeTraits<T> {};
-
-template <cutlass::GemmOperand::Kind kOperand_,
- cutlass::MatrixLayout::Kind kLayout_,
- typename Scalar_,
- typename WmmaShape_>
-struct GemmTestbedTraits<cutlass::WmmaMatrix<kOperand_, kLayout_, Scalar_, WmmaShape_> > {
- static cudaDataType_t const cublas_type = cutlass::TypeTraits<Scalar_>::cublas_type;
- typedef Scalar_ host_type;
- typedef Scalar_ device_type;
- static inline double remove_negative_zero(double x) { return x == -0.0 ? 0.0 : x; }
- static inline double to_print(double x) { return x; }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-template <typename AType, typename BType, typename CType, typename Accumulator, typename Scalar>
-struct GemmTestbed {
- //
- // Type definitions
- //
-
- /// Host tensor for operand A
- typedef cutlass::HostTensor<AType> HostTensorA;
-
- /// Host tensor for operand B
- typedef cutlass::HostTensor<BType> HostTensorB;
-
- /// Host tensor for operand C
- typedef cutlass::HostTensor<CType> HostTensorC;
-
- /// Functor to print errors
- struct PrintErrors {
- /// Equivalently sized integer type
- typedef typename GemmTestbedTraits<CType>::integer_type integer_t;
-
- /// Output stream to write to
- std::ostream& out;
-
- /// Reference tensor view
- cutlass::HostTensorView<CType> const& reference;
-
- /// Computed tensor view
- cutlass::HostTensorView<CType> const& experimental;
-
- /// Errors greater than or this amount result in printing
- integer_t ulps_threshold;
-
- ///
- PrintErrors(std::ostream& _out,
- cutlass::HostTensorView<CType> const& _reference,
- cutlass::HostTensorView<CType> const& _experimental,
- integer_t _ulps_threshold = 1)
- : out(_out),
- reference(_reference),
- experimental(_experimental),
- ulps_threshold(_ulps_threshold) {}
-
- /// Compares one element
- void operator()(CType const& element, typename HostTensorC::Coord_t coord) {
- CType exp = experimental.at(coord);
- CType ref = reference.at(coord);
-
- int64_t int_exp = 0;
- int64_t int_ref = 0;
-
- *reinterpret_cast<CType*>(&int_exp) = exp;
- *reinterpret_cast<CType*>(&int_ref) = ref;
-
- integer_t ulps = integer_t(int_exp - int_ref);
-
- if (std::abs(ulps) >= ulps_threshold) {
- // width in hexadecimal digits of value
- int const width = sizeof(integer_t) * 2;
-
- double relative = double(exp) - double(ref);
- if (ref != CType(0)) {
- relative /= double(ref);
- }
-
- out << "[" << coord << "] expected: " << GemmTestbedTraits<CType>::to_print(ref) << " (0x"
- << std::hex << std::setw(width) << std::setfill('0') << integer_t(int_ref) << std::dec
- << ")"
- << ", got: " << GemmTestbedTraits<CType>::to_print(exp) << " (0x" << std::hex
- << std::setw(width) << std::setfill('0') << integer_t(int_exp) << std::dec << ")"
- << " relative error: " << relative << ", ulps: " << ulps << "\n";
- }
- }
- };
-
- /// Generates random elements
- template <typename T>
- struct RandomGenerator {
- RandomGenerator(int seed = -1, bool only_ones_ = false) : only_ones(only_ones_) { srand(seed); }
-
- T operator()() {
- if (only_ones) {
- return T(1);
- } else {
- int val = (rand() % 16) - 8;
- return T(val);
- }
- }
-
- bool only_ones;
- };
-
- //
- // Data members
- //
-
- /// Status
- //cublasStatus_t status;
-
- /// cuBLAS handle
- //cublasHandle_t handle;
-
- /// cuBLAS GEMM algorithm selector
- //cublasGemmAlgo_t algorithm;
-
- /// A matrix operand
- HostTensorA A;
-
- /// Layout of A matrix
- //cublasOperation_t layout_A;
-
- /// B matrix operand
- HostTensorB B;
-
- /// Layout of B matrix
- //cublasOperation_t layout_B;
-
- /// C matrix operand
- HostTensorC C_initial;
-
- /// Reference result computed on the host
- cutlass::HostTensor<CType, false> ref_host;
-
-
- /// Computed result
- HostTensorC computed;
-
- /// Linear scalaring factor
- Scalar alpha;
-
- /// Linear scaling factor
- Scalar beta;
-
- //
- // Static helpers
- //
- //template <typename T, bool DeviceBacked>
- //static void resize(cutlass::HostTensor<T, DeviceBacked>& tensor,
- // int rows,
- // int columns,
- // cublasOperation_t layout,
- // int ldm = 0) {
- // if (!ldm) {
- // ldm = (layout == CUBLAS_OP_N ? rows : columns);
- // }
-
- // typedef cutlass::Coord<cutlass::HostTensor<T>::Rank> Coord_t;
-
- // size_t matrix_stride = layout == CUBLAS_OP_N ? columns * ldm : rows * ldm;
- // // TODO: Remove that (int) cast.
- // Coord_t stride = cutlass::make_Coord(
- // (int)matrix_stride, layout == CUBLAS_OP_N ? 1 : ldm, layout == CUBLAS_OP_N ? ldm : 1, 1);
- // Coord_t size = cutlass::make_Coord(1, rows, columns, 1);
- // tensor.reset(stride, size);
- //}
-
- /// Helper to resize a matrix with a given size and layout
- template <typename T, bool DeviceBacked>
- static void resize(cutlass::HostTensor<T, DeviceBacked>& tensor,
- int rows,
- int columns,
- int layout,
- int ldm = 0) {
- if (!ldm) {
- ldm = (layout ? rows : columns);
- }
-
- typedef cutlass::Coord<cutlass::HostTensor<T>::Rank> Coord_t;
- size_t matrix_stride = layout ? columns * ldm : rows * ldm;
- // TODO: Remove that (int) cast.
- Coord_t stride = cutlass::make_Coord(
- (int)matrix_stride, layout ? 1 : ldm, layout? ldm : 1, 1);
- Coord_t size = cutlass::make_Coord(1, rows, columns, 1);
- tensor.reset(stride, size);
- }
-
- //
- // Methods
- //
-
- /// Constructs a workspace for verifying GEMM.
- GemmTestbed(int M_,
- int N_,
- int K_,
- int lda,
- int ldb,
- int ldc,
- int layout_a,
- int layout_b,
- Scalar alpha_ = Scalar(1),
- Scalar beta_ = Scalar(0))
- //cublasGemmAlgo_t algorithm_ = CUBLAS_GEMM_DEFAULT,
- //cublasOperation_t layout_c = CUBLAS_OP_N)
- : alpha(alpha_), beta(beta_) {
- //status = cublasCreate(&handle);
- //if (status != CUBLAS_STATUS_SUCCESS) {
- // throw cutlass::cuda_exception("Failed to create CUBLAS handle");
- //}
- printf("GemmTestbed:alpha=%f\n",alpha_);
- printf("GemmTestbed:beta=%f\n",beta_);
- printf("GemmTestbed:lda=%d\n",lda);
- printf("GemmTestbed:ldb=%d\n",ldb);
- printf("GemmTestbed:ldc=%d\n",ldc);
-
- resize(A, M_, K_,layout_a, lda);
- resize(B, K_, N_,layout_b, ldb);
- resize(C_initial, M_, N_,1, ldc);
- resize(ref_host, M_, N_,1, ldc);
- resize(computed, M_, N_,1, ldc);
- }
-
- /// Returns a pointer to the A operand
- typename HostTensorA::DeviceType* ptr_A() const {
- return A.device_data();
- }
-
- /// Stride of A matrix
- int lda() const {
- printf("lda()=%d\n",std::max(A.stride(HostTensorA::Dim_H), A.stride(HostTensorA::Dim_W)));
- return std::max(A.stride(HostTensorA::Dim_H), A.stride(HostTensorA::Dim_W));
- }
-
- /// Returns a pointer to the B operand
- typename HostTensorB::DeviceType* ptr_B() const {
- return B.device_data();
- }
-
- /// Stride of B matrix
- int ldb() const {
- printf("ldb()=%d\n",std::max(B.stride(HostTensorB::Dim_H), B.stride(HostTensorB::Dim_W)));
- return std::max(B.stride(HostTensorB::Dim_H), B.stride(HostTensorB::Dim_W));
- }
-
- /// Returns a pointer to the initial state of the result tensor in device memory
- typename HostTensorC::DeviceType* ptr_C_initial() const {
- return C_initial.device_data();
- }
-
- /// Returns a pointer to the result tensor in device memory
- typename HostTensorC::DeviceType* ptr_computed() const {
- return computed.device_data();
- }
-
- /// Stride of C matrix
- int ldc() const {
- printf("ldc()=%d\n",std::max(C_initial.stride(HostTensorC::Dim_H), C_initial.stride(HostTensorC::Dim_W)));
- return std::max(C_initial.stride(HostTensorC::Dim_H), C_initial.stride(HostTensorC::Dim_W));
- }
-
- /// Returns the number of flops implied by the computation (1 multiply-accumulate = 2 flops)
- uint64_t flops() const { return uint64_t(M()) * uint64_t(N()) * uint64_t(K()) * 2ULL; }
-
- /// Computes the speed of the computation in GFLOPs/s
- double GFLOPs_per_sec(double runtime_ms) const { return double(flops()) / runtime_ms / 1.0e6; }
-
- /// Number of rows of problem
- int M() const {
- printf("M()=%d\n", C_initial.size(HostTensorC::Dim_H));
- return C_initial.size(HostTensorC::Dim_H);
- }
-
- /// Number of columns of problem
- int N() const {
- printf("N()=%d\n", C_initial.size(HostTensorC::Dim_W));
- return C_initial.size(HostTensorC::Dim_W);
- }
-
- /// Number of columns of problem
- int K() const {
- printf("K()=%d\n",A.size(HostTensorA::Dim_W));
- return A.size(HostTensorA::Dim_W);
- }
-
- /// Initializes data, randomly
- void initialize(int seed = -1) {
- A.fill_random(RandomGenerator<AType>(seed));
- B.fill_random(RandomGenerator<BType>(seed + 11));
- C_initial.fill_random(RandomGenerator<CType>(seed + 13,1));
- }
-
- /// Computes the matrix product on the host
- void compute_host() {
- ref_host.fill(C_initial);
-
- std::string results_name = "host_results_before.txt";
- std::ofstream results(results_name.c_str());
- write(results);
-
- ref_host.template gemm<AType, BType, Accumulator, Scalar>(A, B, alpha, beta);
- results_name = "host_results_after.txt";
- std::ofstream results2(results_name.c_str());
- write(results2);
- }
-
- /// Names a probelm based on data type and problem size
- std::string workspace_name() const {
- std::stringstream ss;
- ss << "gemm_" << "t"
- << "t" << "_" << typeid(AType).name() << "_"
- << typeid(BType).name() << "_" << typeid(CType).name() << "_" << typeid(Accumulator).name()
- << "_" << typeid(Scalar).name() << "_" << M() << "x" << N() << "x" << K();
-
- return ss.str();
- }
-
- /// Writes the workspace to an ostream
- std::ostream& write(std::ostream& out) const {
- out << "A = " << A << "\nB = " << B << "\nC_initial = " << C_initial
- << "\ncomputed = " << computed
- << "\nref_host= " << ref_host<< std::endl;
-
- return out;
- }
-
- /// Outputs each mismatching element
- std::ostream& write_errors(std::ostream& out,
- cutlass::HostTensorView<CType> const& experimental,
- cutlass::HostTensorView<CType> const& ref) const {
- PrintErrors printer(out, ref, experimental);
-
- computed.visit(printer);
-
- return out;
- }
-
- /// Sync's all input tensors to device
- void sync_device() {
- A.sync_device();
- B.sync_device();
- C_initial.sync_device();
-
- ref_host.fill(C_initial);
- computed.fill(C_initial);
-
- computed.sync_device();
- }
-
- /// Sync's all output tensors to host
- void sync_host() {
- computed.sync_host();
- }
-
- /// Saves the workspace to files
- void save_workspace(cutlass::HostTensorView<CType> const& experimental,
- cutlass::HostTensorView<CType> const& ref) {
- std::string name = workspace_name();
-
- std::string results_name = name + "_results.txt";
- std::string errors_name = name + "_errors.txt";
-
- std::ofstream results(results_name.c_str());
- std::ofstream errors(errors_name.c_str());
-
- write(results);
- write_errors(errors, experimental, ref);
- }
-
- /// Verifies the contents of C equal the host-side reference
- bool verify_with_host(bool save_on_error = true, bool always_print = false) {
- compute_host();
- computed.sync_host();
-
- bool passed = computed.bit_equals(ref_host);
-
- if ((!passed && save_on_error) || always_print) {
- save_workspace(computed, ref_host);
- }
- return passed;
- }
-};
-
-} // namespace test
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-namespace cutlass {
-inline int convert(cutlass::MatrixLayout::Kind layout) {
- switch (layout) {
- case cutlass::MatrixLayout::kRowMajor:
- return 0;//CUBLAS_OP_T;
- case cutlass::MatrixLayout::kColumnMajor:
- return 1;//CUBLAS_OP_N;
- default:
- break;
- }
- return 1;//CUBLAS_OP_N;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-}
diff --git a/cutlass-example/gpgpusim.config b/cutlass-example/gpgpusim.config
deleted file mode 100644
index 3daa539..0000000
--- a/cutlass-example/gpgpusim.config
+++ /dev/null
@@ -1,151 +0,0 @@
-# This config models the Pascal GP102 (GeForceGTX 1080Ti)
-
-# functional simulator specification
--gpgpu_ptx_instruction_classification 0
--gpgpu_ptx_sim_mode 0
--gpgpu_ptx_force_max_capability 70
-
-# SASS execution (only supported with CUDA >= 4.0)
--gpgpu_ptx_convert_to_ptxplus 0
--gpgpu_ptx_save_converted_ptxplus 0
-
-# high level architecture configuration
--gpgpu_n_clusters 80
--gpgpu_n_cores_per_cluster 1
--gpgpu_n_mem 11
--gpgpu_n_sub_partition_per_mchannel 2
-
-# Pascal clock domains
-#-gpgpu_clock_domains <Core Clock>:<Interconnect Clock>:<L2 Clock>:<DRAM Clock>
-# Pascal NVIDIA TITAN X clock domains are adopted from
-# https://en.wikipedia.org/wiki/GeForce_10_series
--gpgpu_clock_domains 1481.0:2962.0:1481.0:2750.0
-
-# shader core pipeline config
--gpgpu_shader_registers 65536
-
-# This implies a maximum of 64 warps/SM
--gpgpu_shader_core_pipeline 2048:32
--gpgpu_shader_cta 32
--gpgpu_simd_model 1
-
-# Pipeline widths and number of FUs
-# ID_OC_SP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_MEM,EX_WB
-## Pascal GP102 has 4 SP SIMD units and 1 SFU unit
-## we need to scale the number of pipeline registers to be equal to the number of SP units
--gpgpu_pipeline_widths 4,1,1,1,1,4,1,1,1,1,6
--gpgpu_num_sp_units 4
--gpgpu_num_sfu_units 1
-# Instruction latencies and initiation intervals
-# "ADD,MAX,MUL,MAD,DIV"
-# SFU is 32-width in pascal, then dp units initiation is 1 cycle
--ptx_opcode_latency_int 4,13,4,5,145,16,4
--ptx_opcode_initiation_int 1,2,2,2,8,16,4
--ptx_opcode_latency_fp 4,13,4,5,39
--ptx_opcode_initiation_fp 1,2,1,1,4
--ptx_opcode_latency_dp 8,19,8,8,330
--ptx_opcode_initiation_dp 1,2,1,1,130
-
-# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry>
-# ** Optional parameter - Required when mshr_type==Texture Fifo
-# Note: Hashing set index function (H) only applies to a set size of 32 or 64.
-# Pascal GP102 has 96KB Shared memory
-# Pascal GP102 has 64KB L1 cache
-# The default is to disable the L1 cache, unless cache modifieres is used
--gpgpu_cache:dl1 64:128:6,L:L:m:N:H,A:128:8,8
--gpgpu_shmem_size 98304
--gmem_skip_L1D 1
-
-# 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 3MB L2 cache
--gpgpu_cache:dl2 64:128:16,L:B:m:W:L,A:1024:1024,4:0,32 # used to be 128:4
--gpgpu_cache:dl2_texture_only 0
-
-# 4 KB Inst.
--gpgpu_cache:il1 8:128:4,L:R:f:N:L,A:2:48,4
-# 48 KB Tex
--gpgpu_tex_cache:l1 16:128:24,L:R:m:N:L,F:128:4,128:2
-# 12 KB Const
--gpgpu_const_cache:l1 128:64:2,L:R:f:N:L,A:2:64,4
-
-# enable operand collector
-## larger operand collectors and reg_banks are needed for the 4 warp schedulers and 4 SIMD units
--gpgpu_operand_collector_num_units_sp 20
--gpgpu_operand_collector_num_units_sfu 4
-#-gpgpu_operand_collector_num_units_tensor_core 24
--gpgpu_operand_collector_num_units_mem 8
--gpgpu_operand_collector_num_in_ports_sp 4
--gpgpu_operand_collector_num_out_ports_sp 4
--gpgpu_operand_collector_num_in_ports_sfu 1
--gpgpu_operand_collector_num_out_ports_sfu 1
-#-gpgpu_operand_collector_num_in_ports_tensor_core 1
-#-gpgpu_operand_collector_num_out_ports_tensor_core 1
--gpgpu_operand_collector_num_in_ports_mem 10
--gpgpu_operand_collector_num_out_ports_mem 10
-# gpgpu_num_reg_banks should be increased to 32, but it gives an error!
--gpgpu_num_reg_banks 32
-
-# shared memory bankconflict detection
--gpgpu_shmem_num_banks 32
--gpgpu_shmem_limited_broadcast 0
--gpgpu_shmem_warp_parts 1
-
-## In Pascal, a warp scheduler can issue 2 insts per cycle
--gpgpu_max_insn_issue_per_warp 2
-
-# interconnection
--network_mode 1
--inter_config_file config_fermi_islip.icnt
-
-# memory partition latency config
--rop_latency 120
--dram_latency 100
-
-# dram model config
--gpgpu_dram_scheduler 1
-# The DRAM return queue and the scheduler queue together should provide buffer
-# to sustain the memory level parallelism to tolerate DRAM latency
-# To allow 100% DRAM utility, there should at least be enough buffer to sustain
-# the minimum DRAM latency (100 core cycles). I.e.
-# Total buffer space required = 100 x 924MHz / 700MHz = 132
--gpgpu_frfcfs_dram_sched_queue_size 64
--gpgpu_dram_return_queue_size 116
-
-# for NVIDIA GeForceGTX 1080Ti, bus width is 352bits (11 DRAM chips x 32 bits)
-# 11 memory paritions, 4 bytes (1 DRAM chip) per memory partition
-# the atom size of GDDR5X (the smallest read request) is 32 bytes
--gpgpu_n_mem_per_ctrlr 1
--gpgpu_dram_buswidth 4
--gpgpu_dram_burst_length 8
--dram_data_command_freq_ratio 4 # GDDR5X is QDR
--gpgpu_mem_address_mask 1
--gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCC.BCCSSSSS
-
-# Use the same GDDR5 timing from hynix H5GQ1H24AFR
-# disable bank groups for now, set nbkgrp to 1 and tCCDL and tRTPL to 0
--gpgpu_dram_timing_opt "nbk=16:CCD=2:RRD=6:RCD=12:RAS=28:RP=12:RC=40:
- CL=12:WL=4:CDLR=5:WR=12:nbkgrp=1:CCDL=0:RTPL=0"
-
-# Pascal has four schedulers per core
--gpgpu_num_sched_per_core 2
-# Two Level Scheduler with active and pending pools
-#-gpgpu_scheduler two_level_active:6:0:1
-# Loose round robbin scheduler
-#-gpgpu_scheduler lrr
-# Greedy then oldest scheduler
--gpgpu_scheduler gto
-
-# stat collection
--gpgpu_memlatency_stat 14
--gpgpu_runtime_stat 500
--enable_ptx_file_line_stats 1
--visualizer_enabled 0
-
-# power model configs
--power_simulation_enabled 1
--gpuwattch_xml_file gpuwattch_gtx1080Ti.xml
-
-# tracing functionality
-#-trace_enabled 1
-#-trace_components WARP_SCHEDULER,SCOREBOARD
-#-trace_sampling_core 0
-
diff --git a/cutlass-example/gpuwattch_gtx1080Ti.xml b/cutlass-example/gpuwattch_gtx1080Ti.xml
deleted file mode 100755
index 02619ff..0000000
--- a/cutlass-example/gpuwattch_gtx1080Ti.xml
+++ /dev/null
@@ -1,538 +0,0 @@
-<?xml version="1.0" ?>
-<component id="root" name="root">
- <component id="system" name="system">
- <!--McPAT will skip the components if number is set to 0 -->
- <param name="GPU_Architecture" value="1"/><!-- 0-G80; 1-Fermi; others not supported -->
- <param name="number_of_cores" value="28"/>
- <param name="architecture" value="1"/> <!-- fermi:1 quadro:2 other: undefined-->
- <param name="number_of_L1Directories" value="0"/>
- <param name="number_of_L2Directories" value="0"/>
- <param name="number_of_L2s" value="1"/> <!-- This number means how many L2 clusters in each cluster there can be multiple banks/ports -->
- <param name="number_of_L3s" value="0"/> <!-- This number means how many L3 clusters -->
- <param name="number_of_NoCs" value="1"/>
- <param name="homogeneous_cores" value="1"/><!--1 means homo -->
- <param name="homogeneous_L2s" value="1"/>
- <param name="homogeneous_L1Directorys" value="1"/>
- <param name="homogeneous_L2Directorys" value="1"/>
- <param name="homogeneous_L3s" value="1"/>
- <param name="homogeneous_ccs" value="1"/><!--cache coherece hardware -->
- <param name="homogeneous_NoCs" value="1"/>
- <param name="core_tech_node" value="23"/><!-- nm -->
- <param name="target_core_clockrate" value="1481"/><!--MHz -->
- <param name="temperature" value="380"/> <!-- Kelvin -->
- <param name="number_cache_levels" value="2"/>
- <param name="interconnect_projection_type" value="0"/><!--0: agressive wire technology; 1: conservative wire technology -->
- <param name="device_type" value="0"/><!--0: HP(High Performance Type); 1: LSTP(Low standby power) 2: LOP (Low Operating Power) -->
- <param name="longer_channel_device" value="1"/><!-- 0 no use; 1 use when possible -->
- <param name="machine_bits" value="32"/>
- <param name="virtual_address_width" value="32"/>
- <param name="physical_address_width" value="32"/>
- <param name="virtual_memory_page_size" value="4096"/>
- <param name="idle_core_power" value="1.59"/><!-- idle core power for GTX479 -->
- <!--param name="scaling_coefficients" value="10,0.0884816,10,10,8,10,4.12782,10,2.48832,10,10,10,4.29982,0.387764,0.0714269,0.14302,0.01,0.546811,0.485351,0.806633,0.818073,1.9207,100,100,100,87.9303,100,10,4.3548,10"/-->
- <param name="TOT_INST" value="10" />
- <param name="FP_INT" value="10" />
- <param name="IC_H" value="0.001" />
- <param name="IC_M" value="10" />
- <param name="DC_RH" value="1" />
- <param name="DC_RM" value="1" />
- <param name="DC_WH" value="1" />
- <param name="DC_WM" value="1" />
- <param name="TC_H" value="0.001" />
- <param name="TC_M" value="10" />
- <param name="CC_H" value="4.5071" />
- <param name="CC_M" value="10" />
- <param name="SHRD_ACC" value="10" />
- <param name="REG_RD" value="1.6294" />
- <param name="REG_WR" value="0.5031" />
- <param name="NON_REG_OPs" value="0.01" />
- <param name="SP_ACC" value="10" />
- <param name="SFU_ACC" value="0.0082" />
- <param name="FPU_ACC" value="0.4126" />
- <param name="MEM_RD" value="0.1234" />
- <param name="MEM_WR" value="0.001" />
- <param name="MEM_PRE" value="0.001" />
- <param name="L2_RH" value="100" />
- <param name="L2_RM" value="100" />
- <param name="L2_WH" value="100" />
- <param name="L2_WM" value="42.6966" />
- <param name="NOC_A" value="100" />
- <param name="PIPE_A" value="44.8085" />
- <param name="IDLE_CORE_N" value="2.0382"/>
- <param name="CONST_DYNAMICN" value="5.0005" />
- <stat name="num_idle_cores" value="0"/><!-- Average Number of idle cores during this period -->
- <stat name="total_cycles" value="total_cycles_match_mcpat"/>
- <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
- <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
- <!--This page size(B) is complete different from the page size in Main memo secction. this page size is the size of
- virtual memory from OS/Archi perspective; the page size in Main memo secction is the actuall physical line in a DRAM bank -->
- <!-- *********************** cores ******************* -->
- <component id="system.core0" name="core0">
- <!-- Core property -->
- <param name="clock_rate" value="1481"/>
- <param name="instruction_length" value="32"/>
- <param name="opcode_width" value="9"/>
- <!-- address width determins the tag_width in Cache, LSQ and buffers in cache controller
- default value is machine_bits, if not set -->
- <param name="machine_type" value="1"/><!-- 1 inorder; 0 OOO-->
- <!-- inorder/OoO -->
- <param name="number_hardware_threads" value="32"/>
- <!-- number_instruction_fetch_ports(icache ports) is always 1 in single-thread processor,
- it only may be more than one in SMT processors. BTB ports always equals to fetch ports since
- branch information in consective branch instructions in the same fetch group can be read out from BTB once.-->
- <param name="fetch_width" value="1"/>
- <!-- fetch_width determins the size of cachelines of L1 cache block -->
- <param name="number_instruction_fetch_ports" value="1"/>
- <param name="decode_width" value="1"/>
- <!-- decode_width determins the number of ports of the
- renaming table (both RAM and CAM) scheme -->
- <param name="issue_width" value="2"/>
- <!-- issue_width determins the number of ports of Issue window and other logic
- as in the complexity effective proccessors paper; issue_width==dispatch_width -->
- <param name="commit_width" value="2"/>
- <!-- commit_width determins the number of ports of register files -->
- <param name="fp_issue_width" value="1"/>
- <param name="prediction_width" value="0"/>
- <!-- number of branch instructions can be predicted simultannouesl-->
- <!-- Current version of McPAT does not distinguish int and floating point pipelines
- Theses parameters are reserved for future use.-->
- <param name="pipelines_per_core" value="1,1"/>
- <!--integer_pipeline and floating_pipelines, if the floating_pipelines is 0, then the pipeline is shared-->
- <param name="pipeline_depth" value="8,8"/>
- <!-- pipeline depth of int and fp, if pipeline is shared, the second number is the average cycles of fp ops -->
- <!-- issue and exe unit-->
- <param name="ALU_per_core" value="32"/>
- <!-- contains an adder, a shifter, and a logical unit -->
- <param name="MUL_per_core" value="4"/>
- <!-- For MUL and Div -->
- <param name="FPU_per_core" value="32"/>
- <!-- buffer between IF and ID stage -->
- <param name="instruction_buffer_size" value="1"/>
- <!-- buffer between ID and sche/exe stage -->
- <param name="decoded_stream_buffer_size" value="1"/>
- <param name="instruction_window_scheme" value="0"/><!-- 0 PHYREG based, 1 RSBASED-->
- <!-- McPAT support 2 types of OoO cores, RS based and physical reg based-->
- <param name="instruction_window_size" value="1"/>
- <param name="fp_instruction_window_size" value="1"/>
- <!-- the instruction issue Q as in Alpha 21264; The RS as in Intel P6 -->
- <param name="ROB_size" value="0"/>
- <!-- each in-flight instruction has an entry in ROB -->
- <!-- registers -->
- <!-- SM parameters Added by Syed Gilani -->
- <param name="rf_banks" value="32"/>
- <param name="simd_width" value="32"/>
- <param name="collector_units" value="32"/>
- <param name="core_clock_ratio" value="2"/>
- <param name="warp_size" value="32"/>
-
- <param name="archi_Regs_IRF_size" value="65536"/>
- <param name="archi_Regs_FRF_size" value="32"/>
- <!-- if OoO processor, phy_reg number is needed for renaming logic,
- renaming logic is for both integer and floating point insts. -->
- <param name="phy_Regs_IRF_size" value="32"/>
- <param name="phy_Regs_FRF_size" value="32"/>
- <!-- rename logic -->
- <param name="rename_scheme" value="0"/>
- <!-- can be RAM based(0) or CAM based(1) rename scheme
- RAM-based scheme will have free list, status table;
- CAM-based scheme have the valid bit in the data field of the CAM
- both RAM and CAM need RAM-based checkpoint table, checkpoint_depth=# of in_flight instructions;
- Detailed RAT Implementation see TR -->
- <param name="register_windows_size" value="0"/>
- <!-- how many windows in the windowed register file, sun processors;
- no register windowing is used when this number is 0 -->
- <!-- In OoO cores, loads and stores can be issued whether inorder(Pentium Pro) or (OoO)out-of-order(Alpha),
- They will always try to exeute out-of-order though. -->
- <param name="LSU_order" value="inorder"/>
- <param name="store_buffer_size" value="32"/>
- <!-- By default, in-order cores do not have load buffers -->
- <param name="load_buffer_size" value="32"/>
- <!-- number of ports refer to sustainable concurrent memory accesses -->
- <param name="memory_ports" value="2"/>
- <!-- max_allowed_in_flight_memo_instructions determins the # of ports of load and store buffer
- as well as the ports of Dcache which is connected to LSU -->
- <!-- dual-pumped Dcache can be used to save the extra read/write ports -->
- <param name="RAS_size" value="1"/>
- <!-- general stats, defines simulation periods;require total, idle, and busy cycles for senity check -->
- <!-- please note: if target architecture is X86, then all the instrucions refer to (fused) micro-ops -->
- <stat name="total_instructions" value="total_instructions_match_mcpat"/>
- <stat name="int_instructions" value="int_instruction_match_mcpat"/>
- <stat name="fp_instructions" value="flt_instruction_match_mcpat"/>
- <stat name="branch_instructions" value="branch_instruction_match_mcpat"/>
- <stat name="branch_mispredictions" value="0"/>
- <stat name="load_instructions" value="load_instruction_match_mcpat"/>
- <stat name="store_instructions" value="store_instruction_match_mcpat"/>
- <stat name="committed_instructions" value="total_instructions_match_mcpat"/>
- <stat name="committed_int_instructions" value="int_instruction_match_mcpat"/>
- <stat name="committed_fp_instructions" value="flt_instruction_match_mcpat"/>
- <stat name="pipeline_duty_cycle" value="0.6"/><!--<=1, runtime_ipc/peak_ipc; averaged for all cores if homogenous -->
- <!-- the following cycle stats are used for heterogeneouse cores only,
- please ignore them if homogeneouse cores -->
- <stat name="total_cycles" value="total_cycles_match_mcpat"/>
- <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
- <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
- <!-- instruction buffer stats -->
- <!-- ROB stats, both RS and Phy based OoOs have ROB
- performance simulator should capture the difference on accesses,
- otherwise, McPAT has to guess based on number of commited instructions. -->
- <stat name="ROB_reads" value="263886"/>
- <stat name="ROB_writes" value="263886"/>
- <!-- RAT accesses -->
- <stat name="rename_accesses" value="263886"/>
- <stat name="fp_rename_accesses" value="263886"/>
- <!-- decode and rename stage use this, should be total ic - nop -->
- <!-- Inst window stats -->
- <stat name="inst_window_reads" value="263886"/>
- <stat name="inst_window_writes" value="263886"/>
- <stat name="inst_window_wakeup_accesses" value="263886"/>
- <stat name="fp_inst_window_reads" value="263886"/>
- <stat name="fp_inst_window_writes" value="263886"/>
- <stat name="fp_inst_window_wakeup_accesses" value="263886"/>
- <!-- RF accesses -->
- <stat name="int_regfile_reads" value="int_register_read_access_match_mcpat"/>
- <stat name="float_regfile_reads" value="int_register_write_access_match_mcpat"/>
- <stat name="int_regfile_writes" value="float_register_read_access_match_mcpat"/>
- <stat name="float_regfile_writes" value="float_register_write_access_match_mcpat"/>
-
- <!-- The following stat is for operand collector power - Added by Syed -->
- <stat name="non_rf_operands" value="0"/>
-
- <!-- accesses to the working reg -->
- <stat name="function_calls" value="0"/>
- <stat name="context_switches" value="0"/> <!--not used in the McPAT -->
- <!-- Number of Windowes switches (number of function calls and returns)-->
- <!-- Alu stats by default, the processor has one FPU that includes the divider and
- multiplier. The fpu accesses should include accesses to multiplier and divider -->
- <stat name="ialu_accesses" value="ialu_accesses_match_mcpat"/>
- <stat name="fpu_accesses" value="fpu_accesses_match_mcpat"/>
- <stat name="mul_accesses" value="mul_accesses_match_mcpat"/>
- <stat name="cdb_alu_accesses" value="0"/>
- <stat name="cdb_mul_accesses" value="0"/>
- <stat name="cdb_fpu_accesses" value="0"/>
- <!-- multiple cycle accesses should be counted multiple times,
- otherwise, McPAT can use internal counter for different floating point instructions
- to get final accesses. But that needs detailed info for floating point inst mix -->
- <!-- currently the performance simulator should
- make sure all the numbers are final numbers,
- including the explicit read/write accesses,
- and the implicite accesses such as replacements and etc.
- Future versions of McPAT may be able to reason the implicite access
- based on param and stats of last level cache
- The same rule applies to all cache access stats too! -->
- <!-- following is AF for max power computation.
- Do not change them, unless you understand them-->
- <stat name="IFU_duty_cycle" value="0.25"/>
- <stat name="LSU_duty_cycle" value="0.25"/>
- <stat name="MemManU_I_duty_cycle" value="1"/>
- <stat name="MemManU_D_duty_cycle" value="0.25"/>
- <stat name="ALU_duty_cycle" value="0.9"/>
- <stat name="MUL_duty_cycle" value="0.5"/>
- <stat name="FPU_duty_cycle" value="1"/><!-- FPU numbers are already average -->
- <stat name="ALU_cdb_duty_cycle" value="0.9"/>
- <stat name="MUL_cdb_duty_cycle" value="0.5"/>
- <stat name="FPU_cdb_duty_cycle" value="15"/>
- <component id="system.core0.predictor" name="PBT">
- <!-- branch predictor; tournament predictor see Alpha implementation -->
- <param name="local_predictor_size" value="10,3"/>
- <param name="local_predictor_entries" value="1024"/>
- <param name="global_predictor_entries" value="4096"/>
- <param name="global_predictor_bits" value="2"/>
- <param name="chooser_predictor_entries" value="4096"/>
- <param name="chooser_predictor_bits" value="2"/>
- <!-- These parameters can be combined like below in next version
- <param name="load_predictor" value="10,3,1024"/>
- <param name="global_predictor" value="4096,2"/>
- <param name="predictor_chooser" value="4096,2"/>
- -->
- </component>
- <component id="system.core0.itlb" name="itlb">
- <param name="number_entries" value="1"/>
- <stat name="total_accesses" value="0"/>
- <stat name="total_misses" value="0"/>
- <stat name="conflicts" value="0"/>
- <!-- there is no write requests to itlb although writes happen to itlb after miss,
- which is actually a replacement -->
- </component>
- <component id="system.core0.icache" name="icache">
- <!-- there is no write requests to itlb although writes happen to it after miss,
- which is actually a replacement -->
- <param name="icache_config" value="16384,128,4,1,1,3,8,0"/>
- <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
- <!-- cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate -->
- <param name="buffer_sizes" value="16, 16, 16,0"/>
- <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
- <stat name="read_accesses" value="total_instructions_match_mcpat"/>
- <stat name="read_misses" value="0"/>
- <stat name="conflicts" value="0"/>
- </component>
- <component id="system.core0.dtlb" name="dtlb">
- <param name="number_entries" value="1"/>
- <stat name="total_accesses" value="0"/>
- <stat name="total_misses" value="0"/>
- <stat name="conflicts" value="0"/>
- </component>
- <component id="system.core0.ccache" name="ccache">
- <!-- all the buffer related are optional -->
- <param name="ccache_config" value="16384,64,2,1,1,3,8,0"/>
- <param name="buffer_sizes" value="16, 16, 16, 0"/>
- <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
- <stat name="read_accesses" value="ccache_read_accesses_match_mcpat"/>
- <stat name="write_accesses" value="0"/>
- <stat name="read_misses" value="ccache_read_misses_match_mcpat"/>
- <stat name="write_misses" value="0"/>
- <stat name="conflicts" value="0"/>
- </component>
- <component id="system.core0.tcache" name="tcache">
- <!-- all the buffer related are optional -->
- <param name="tcache_config" value="49152,128,8,1,1,3,8,0"/>
- <param name="buffer_sizes" value="16, 16, 16, 0"/>
- <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
- <stat name="read_accesses" value="tcache_read_accesses_match_mcpat"/>
- <stat name="write_accesses" value="0"/>
- <stat name="read_misses" value="tcache_read_misses_match_mcpat"/>
- <stat name="write_misses" value="0"/>
- <stat name="conflicts" value="0"/>
- </component>
- <!--model the shared memory by mimicing dcache-->
- <component id="system.core0.sharedmemory" name="sharedmemory">
- <!-- all the buffer related are optional -->
- <param name="sharedmemory_config" value="98304,16,1,16,1,3,16,0"/>
- <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
- <param name="buffer_sizes" value="16, 16, 16, 16"/>
- <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
- <stat name="read_accesses" value="sharedmemory_read_access_match_mcpat"/>
- <stat name="write_accesses" value="sharedmemory_write_access_match_mcpat"/>
- <stat name="read_misses" value="0"/>
- <stat name="write_misses" value="0"/>
- <stat name="conflicts" value="0"/>
- </component>
- <component id="system.core0.dcache" name="dcache">
- <!-- all the buffer related are optional -->
- <param name="dcache_config" value="16384,32,4,1,1,3,8,0"/>
- <param name="buffer_sizes" value="16, 16, 16, 0"/>
- <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
- <stat name="read_accesses" value="dcache_read_access_match_mcpat"/>
- <stat name="write_accesses" value="dcache_write_access_match_mcpat"/>
- <stat name="read_misses" value="dcache_read_miss_match_mcpat"/>
- <stat name="write_misses" value="dcache_write_miss_match_mcpat"/>
- <stat name="conflicts" value="0"/>
- </component>
- <component id="system.core0.BTB" name="BTB">
- <!-- all the buffer related are optional -->
- <param name="BTB_config" value="8192,4,2,1, 1,3"/>
- <!-- the parameters are capacity,block_width,associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
- </component>
- </component>
- <component id="system.L1Directory0" name="L1Directory0">
- <param name="Directory_type" value="0"/>
- <!--0 cam based shadowed tag. 1 directory cache -->
- <param name="Dir_config" value="2048,1,0,1, 4, 4,8"/>
- <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
- <param name="buffer_sizes" value="8, 8, 8, 8"/>
- <!-- all the buffer related are optional -->
- <param name="clockrate" value="1400"/>
- <param name="ports" value="1,1,1"/>
- <!-- number of r, w, and rw search ports -->
- <param name="device_type" value="0"/>
- <!-- altough there are multiple access types,
- Performance simulator needs to cast them into reads or writes
- e.g. the invalidates can be considered as writes -->
- <stat name="read_accesses" value="800000"/>
- <stat name="write_accesses" value="27276"/>
- <stat name="read_misses" value="1632"/>
- <stat name="write_misses" value="183"/>
- <stat name="conflicts" value="20"/>
- <stat name="duty_cycle" value="0.45"/>
- </component>
- <component id="system.L2Directory0" name="L2Directory0">
- <param name="Directory_type" value="1"/>
- <!--0 cam based shadowed tag. 1 directory cache -->
- <param name="Dir_config" value="1048576,16,16,1,2, 100"/>
- <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
- <param name="buffer_sizes" value="8, 8, 8, 8"/>
- <!-- all the buffer related are optional -->
- <param name="clockrate" value="1400"/>
- <param name="ports" value="1,1,1"/>
- <!-- number of r, w, and rw search ports -->
- <param name="device_type" value="0"/>
- <!-- altough there are multiple access types,
- Performance simulator needs to cast them into reads or writes
- e.g. the invalidates can be considered as writes -->
- <stat name="read_accesses" value="0"/>
- <stat name="write_accesses" value="0"/>
- <stat name="read_misses" value="0"/>
- <stat name="write_misses" value="0"/>
- <stat name="conflicts" value="0"/>
- <stat name="duty_cycle" value="0.45"/>
- </component>
- <component id="system.L20" name="L20">
- <!-- all the buffer related are optional -->
- <param name="L2_config" value="131072,128,16,1, 4,23, 64, 1"/>
- <!-- consider 4-way bank interleaving for Niagara 1 -->
- <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
- <param name="buffer_sizes" value="16, 16, 16, 16"/>
- <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
- <param name="clockrate" value="2962"/>
- <param name="ports" value="1,1,1"/>
- <!-- number of r, w, and rw ports -->
- <param name="device_type" value="0"/>
- <stat name="read_accesses" value="200000"/>
- <stat name="write_accesses" value="0"/>
- <stat name="read_misses" value="0"/>
- <stat name="write_misses" value="0"/>
- <stat name="conflicts" value="0"/>
- <stat name="duty_cycle" value="0.5"/>
- </component>
-
-<!--**********************************************************************-->
-<component id="system.L30" name="L30">
- <param name="L3_config" value="1048576,64,16,1, 2,100, 64,1"/>
- <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
- <param name="clockrate" value="3500"/>
- <param name="ports" value="1,1,1"/>
- <!-- number of r, w, and rw ports -->
- <param name="device_type" value="0"/>
- <param name="buffer_sizes" value="16, 16, 16, 16"/>
- <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
- <stat name="read_accesses" value="58824"/>
- <stat name="write_accesses" value="27276"/>
- <stat name="read_misses" value="1632"/>
- <stat name="write_misses" value="183"/>
- <stat name="conflicts" value="0"/>
- <stat name="duty_cycle" value="0.35"/>
- </component>
-
-
-<!--**********************************************************************-->
- <component id="system.NoC0" name="noc0">
- <param name="clockrate" value="700"/>
- <param name="type" value="1"/>
- <!-- 1 NoC, O bus -->
- <param name="horizontal_nodes" value="2"/>
- <param name="vertical_nodes" value="1"/>
- <param name="has_global_link" value="0"/>
- <!-- 1 has global link, 0 does not have global link -->
- <param name="link_throughput" value="1"/><!--w.r.t clock -->
- <param name="link_latency" value="1"/><!--w.r.t clock -->
- <!-- througput >= latency -->
- <!-- Router architecture -->
- <param name="input_ports" value="6"/>
- <param name="output_ports" value="6"/>
- <param name="virtual_channel_per_port" value="1"/>
- <!-- input buffer; in classic routers only input ports need buffers -->
- <param name="flit_bits" value="32"/>
- <param name="input_buffer_entries_per_vc" value="1"/><!--VCs within the same ports share input buffers whose size is propotional to the number of VCs-->
- <param name="chip_coverage" value="1"/>
- <!-- When multiple NOC present, one NOC will cover part of the whole chip. chip_coverage <=1 -->
- <stat name="total_accesses" value="0"/>
- <!-- This is the number of total accesses within the whole network not for each router -->
- <stat name="duty_cycle" value="0.6"/>
- </component>
-<!--**********************************************************************-->
-<!--**********************************************************************-->
-
- <component id="system.mem" name="mem">
- <!-- Main memory property -->
- <param name="mem_tech_node" value="23"/>
- <param name="device_clock" value="200"/><!--MHz, this is clock rate of the actual memory device, not the FSB -->
- <param name="peak_transfer_rate" value="3200"/><!--MB/S-->
- <param name="internal_prefetch_of_DRAM_chip" value="4"/>
- <!-- 2 for DDR, 4 for DDR2, 8 for DDR3...-->
- <!-- the device clock, peak_transfer_rate, and the internal prefetch decide the DIMM property -->
- <!-- above numbers can be easily found from Wikipedia -->
- <param name="capacity_per_channel" value="4096"/> <!-- MB -->
- <!-- capacity_per_Dram_chip=capacity_per_channel/number_of_dimms/number_ranks/Dram_chips_per_rank
- Current McPAT assumes single DIMMs are used.-->
- <param name="number_ranks" value="2"/>
- <param name="num_banks_of_DRAM_chip" value="6"/>
- <param name="Block_width_of_DRAM_chip" value="64"/> <!-- B -->
- <param name="output_width_of_DRAM_chip" value="8"/>
- <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
- <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
- <param name="page_size_of_DRAM_chip" value="8"/> <!-- 8 or 16 -->
- <param name="burstlength_of_DRAM_chip" value="8"/>
- <stat name="memory_accesses" value="1052"/>
- <stat name="memory_reads" value="1052"/>
- <stat name="memory_writes" value="1052"/>
- </component>
- <component id="system.mc" name="mc">
- <!-- Memeory controllers are for DDR(2,3...) DIMMs -->
- <!-- current version of McPAT uses published values for base parameters of memory controller
- improvments on MC will be added in later versions. -->
- <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
- <param name="mc_clock" value="1848"/><!--DIMM IO bus clock rate MHz DDR2-400 for Niagara 1-->
- <param name="peak_transfer_rate" value="29568"/><!--MB/S Syed: GTX 470 has 177.4GB/s mem transfer rate with 6 MCs -->
- <param name="block_size" value="64"/><!--B-->
- <param name="number_mcs" value="6"/><!-- 6 GDDR5 memory controllers -->
- <!-- current McPAT only supports homogeneous memory controllers -->
- <param name="memory_channels_per_mc" value="2"/>
- <param name="number_ranks" value="1"/>
- <param name="withPHY" value="0"/>
- <!-- # of ranks of each channel-->
- <param name="req_window_size_per_channel" value="16"/>
- <param name="IO_buffer_size_per_channel" value="16"/>
- <param name="databus_width" value="32"/>
- <param name="addressbus_width" value="32"/>
- <param name="PRT_entries" value="32"/>
- <!-- # of empirical DRAM model parameter -->
- <param name="dram_cmd_coeff" value="0"/>
- <param name="dram_act_coeff" value="0"/>
- <param name="dram_nop_coeff" value="0"/>
- <param name="dram_activity_coeff" value="0"/>
- <param name="dram_pre_coeff" value="3.8475e-8f"/>
- <param name="dram_rd_coeff" value="7.74707143e-8f"/>
- <param name="dram_wr_coeff" value="3.54664286e-8f"/>
- <param name="dram_req_coeff" value="0"/>
- <param name="dram_const_coeff" value="0"/>
-
- <!-- McPAT will add the control bus width to the addressbus width automatically -->
- <stat name="memory_accesses" value="memory_accesses_match_mcpat"/>
- <stat name="memory_reads" value="memory_reads_match_mcpat"/>
- <stat name="memory_writes" value="memory_writes_match_mcpat"/>
- <!-- McPAT does not track individual mc, instead, it takes the total accesses and calculate
- the average power per MC or per channel. This is sufficent for most application.
- Further trackdown can be easily added in later versions. -->
- </component>
-<!--**********************************************************************-->
- <component id="system.niu" name="niu">
- <!-- On chip 10Gb Ethernet NIC, including XAUI Phy and MAC controller -->
- <!-- For a minimum IP packet size of 84B at 10Gb/s, a new packet arrives every 67.2ns.
- the low bound of clock rate of a 10Gb MAC is 150Mhz -->
- <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
- <param name="clockrate" value="350"/>
- <param name="number_units" value="0"/> <!-- unlike PCIe and memory controllers, each Ethernet controller only have one port -->
- <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
- <stat name="total_load_perc" value="0.7"/> <!-- ratio of total achived load to total achivable bandwidth -->
- <!-- McPAT does not track individual nic, instead, it takes the total accesses and calculate
- the average power per nic or per channel. This is sufficent for most application. -->
- </component>
-<!--**********************************************************************-->
- <component id="system.pcie" name="pcie">
- <!-- On chip PCIe controller, including Phy-->
- <!-- For a minimum PCIe packet size of 84B at 8Gb/s per lane (PCIe 3.0), a new packet arrives every 84ns.
- the low bound of clock rate of a PCIe per lane logic is 120Mhz -->
- <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
- <param name="withPHY" value="1"/>
- <param name="clockrate" value="350"/>
- <param name="number_units" value="0"/>
- <param name="num_channels" value="8"/> <!-- 2 ,4 ,8 ,16 ,32 -->
- <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
- <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
- <!-- McPAT does not track individual pcie controllers, instead, it takes the total accesses and calculate
- the average power per pcie controller or per channel. This is sufficent for most application. -->
- </component>
-<!--**********************************************************************-->
- <component id="system.flashc" name="flashc">
- <param name="number_flashcs" value="0"/>
- <param name="type" value="1"/> <!-- 1: low power; 0 high performance -->
- <param name="withPHY" value="1"/>
- <param name="peak_transfer_rate" value="200"/><!--Per controller sustainable reak rate MB/S -->
- <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
- <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
- <!-- McPAT does not track individual flash controller, instead, it takes the total accesses and calculate
- the average power per fc or per channel. This is sufficent for most application -->
- </component>
-<!--**********************************************************************-->
-
- </component>
-</component>
diff --git a/cutlass-example/half.h b/cutlass-example/half.h
deleted file mode 100644
index ee536e5..0000000
--- a/cutlass-example/half.h
+++ /dev/null
@@ -1,743 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*!
- \file
- \brief Host-side implementation of half-precision float
-*/
-
-#pragma once
-
-#include <stdint.h>
-#include <cmath>
-#include <limits>
-#include <utility>
-#include <utility>
-
-#include <iomanip>
-#include <istream>
-#include <ostream>
-
-#include <cuda_fp16.h>
-
-namespace cutlass {
-
-/// IEEE binary16 floating-point value
-class half_t {
- public:
- half_t();
- half_t(int); /// conversion from integer
- half_t(float); /// conversion from fp32
- half_t(double); /// conversion from fp64
-
- static half_t bitcast(unsigned short); /// bitcast performs no conversion
-
- static half_t convert(float const&); /// FP conversion - round toward nearest even
- static float convert(unsigned short const&); /// floating point conversion to fp32
-
- static half_t zero() { return bitcast(0); } /// +zero
- static half_t one() { return bitcast(0x3c00); } /// one
- static half_t nan() { return bitcast(0x7fff); } /// canonical not a number
- static half_t inf() { return bitcast(0x7c00); } /// +infinity
- static half_t ninf() { return bitcast(0xfc00); } /// -infinity
- static half_t epsilon() { return bitcast(0x1000); } /// Machine epsilon
-
- bool signbit() const; /// sign bit - true: negative, false: positive
- int exponent() const; /// unbiased exponent
- unsigned short mantissa() const; /// mantissa bits
-
- bool isfinite() const; /// true if neither inf nor nan
- bool isinf() const; /// true if value is + or - infinity
- bool isnan() const; /// true if value is not a number
- bool isnormal() const; /// true if nonzero value is normalized
- bool iszero() const; /// true if value is + or - zero
-
- bool operator==(half_t const&) const;
- bool operator!=(half_t const&) const;
- bool operator==(float const&) const;
- bool operator!=(float const&) const;
-
- bool operator<(half_t const&) const;
- bool operator<=(half_t const&) const;
- bool operator>(half_t const&) const;
- bool operator>=(half_t const&) const;
-
- half_t operator+(half_t const&) const;
- half_t operator-() const;
- half_t operator-(half_t const&) const;
- half_t operator*(half_t const&)const;
- half_t operator/(half_t const&) const;
-
- half_t& operator+=(half_t const&);
- half_t& operator-=(half_t const&);
- half_t& operator*=(half_t const&);
- half_t& operator/=(half_t const&);
-
- half_t& operator++();
- half_t& operator--();
- half_t operator++(int);
- half_t operator--(int);
-
- operator bool() const; /// false if zero
- operator int() const; /// conversion to int
- operator float() const; /// conversion to fp32
- operator half() const; /// conversion to half
-
- uint16_t& raw() { return x; }
- uint16_t raw() const { return x; }
-
- public:
- /// data
- unsigned short x;
-};
-
-/// Packed pair of half-precision elements
-class half2_t {
- public:
- half2_t();
- half2_t(half_t lo, half_t hi);
- half2_t(std::pair<float, float> const&);
- explicit half2_t(unsigned data);
-
- half2_t operator+(half2_t const&) const;
- half2_t operator-(half2_t const&) const;
- half2_t operator*(half2_t const&)const;
- half2_t operator/(half2_t const&) const;
-
- half2_t& operator+=(half2_t const&);
- half2_t& operator-=(half2_t const&);
- half2_t& operator*=(half2_t const&);
- half2_t& operator/=(half2_t const&);
-
- float dot(half2_t const&) const; /// dot product with single-precision accumulation
- float dot(half2_t const&, float) const; /// dot product with single-precision accumulation
-
- half_t doth(half2_t const&) const; /// dot product with half_t-precision accumulation
- half_t doth(half2_t const&, half_t) const; /// dot product with half_t-precision accumulation
-
- unsigned packed() const;
-
- operator std::pair<float, float>() const;
- operator unsigned() const;
-
- public:
- half_t lo;
- half_t hi;
-};
-
-template <typename Dest, typename Src>
-Dest bitcast(Src const&);
-template <>
-float bitcast<float, unsigned>(unsigned const&);
-template <>
-float bitcast<float, int>(int const&);
-template <>
-unsigned bitcast<unsigned, float>(float const&);
-template <>
-half_t bitcast<half_t, unsigned short>(unsigned short const&);
-template <>
-unsigned short bitcast<unsigned short, half_t>(half_t const&);
-template <>
-half bitcast<half, unsigned short>(unsigned short const&);
-} // namespace cutlass
-
-cutlass::half_t operator+(float, cutlass::half_t const&);
-cutlass::half_t operator-(float, cutlass::half_t const&);
-cutlass::half_t operator*(float, cutlass::half_t const&);
-cutlass::half_t operator/(float, cutlass::half_t const&);
-
-std::ostream& operator<<(std::ostream&, cutlass::half_t const&); /// writes a half_t
-std::istream& operator>>(std::istream&, cutlass::half_t&); /// reads a half_t
-
-#ifdef BOOST_LEXICAL_CAST_INCLUDED
-namespace boost {
-
-/// lexical cast from string to half_t
-template <>
-cutlass::half_t lexical_cast<cutlass::half_t>(std::string const& arg);
-
-/// lexical cast from half_t to string
-template <>
-std::string lexical_cast<std::string>(cutlass::half_t const& arg);
-} // namespace boost
-#endif
-
-#define HLF_MANT_DIG 10
-
-namespace std {
-
-cutlass::half_t abs(cutlass::half_t const&); /// absolute value
-
-bool isnan(cutlass::half_t const&); /// true if argument is NaN
-
-bool isfinite(cutlass::half_t const&); /// true if argument is neither NaN nor infinity
-
-cutlass::half_t nanh(const char* = 0); /// returns a not-a-number
-
-bool isinf(cutlass::half_t const&); /// returns true if argument is infinitey (+ or -)
-
-bool isnormal(
- cutlass::half_t const&); /// returns true if argument is normal (neither zero nor infinity)
-
-int fpclassify(cutlass::half_t const&); /// returns a flag classifying floating-point value
-
-bool signbit(cutlass::half_t const&); /// returns true if negative, false if positive
-
-cutlass::half_t sqrt(cutlass::half_t const&); /// square root of half_t
-
-/// Numeric limits
-template <>
-struct numeric_limits<cutlass::half_t> {
- static bool const is_specialized = true;
- static bool const is_signed = true;
- static bool const is_integer = false;
- static bool const is_exact = false;
- static bool const has_infinity = true;
- static bool const has_quiet_NaN = true;
- static bool const has_signaling_NaN = false;
- static std::float_denorm_style const has_denorm = std::denorm_present;
- static bool const has_denorm_loss = true;
- static std::float_round_style const round_style = std::round_to_nearest;
- static bool const is_iec559 = false;
- static bool const is_bounded = true;
- static bool const is_modulo = false;
- static int const digits = HLF_MANT_DIG;
-
- static cutlass::half_t min() { return cutlass::half_t::bitcast(0x0001); }
-
- static cutlass::half_t lowest() { return cutlass::half_t::bitcast(0xfbff); }
-
- static cutlass::half_t max() { return cutlass::half_t::bitcast(0x7bff); }
-
- /// Returns smallest finite value
- static cutlass::half_t epsilon() { return cutlass::half_t::epsilon(); }
-
- /// Returns smallest finite value
- static cutlass::half_t round_error() { return cutlass::half_t(0.5f); }
-
- /// Returns smallest finite value
- static cutlass::half_t infinity() { return cutlass::half_t::inf(); }
-
- /// Returns smallest finite value
- static cutlass::half_t quiet_NaN() { return cutlass::half_t::nan(); }
-
- /// Returns smallest finite value
- static cutlass::half_t signaling_NaN() { return cutlass::half_t::nan(); }
-
- /// Returns smallest finite value
- static cutlass::half_t denorm_min() { return cutlass::half_t::bitcast(0x0001); }
-};
-} // namespace std
-
-//
-//
-//
-
-inline cutlass::half_t cutlass::half_t::bitcast(unsigned short _x) {
- half_t h;
- h.x = _x;
- return h;
-}
-
-/// FP32 -> FP16 conversion - rounds to nearest even
-inline cutlass::half_t cutlass::half_t::convert(float const& flt) {
- // software implementation rounds toward nearest even
- unsigned const& s = *reinterpret_cast<unsigned const*>(&flt);
- uint16_t sign = uint16_t((s >> 16) & 0x8000);
- int16_t exp = uint16_t(((s >> 23) & 0xff) - 127);
- int mantissa = s & 0x7fffff;
- uint16_t u = 0;
-
- if ((s & 0x7fffffff) == 0) {
- // sign-preserving zero
- return cutlass::half_t::bitcast(sign);
- }
-
- if (exp > 15) {
- if (exp == 128 && mantissa) {
- // not a number
- u = 0x7fff;
- } else {
- // overflow to infinity
- u = sign | 0x7c00;
- }
- return cutlass::half_t::bitcast(u);
- }
-
- int sticky_bit = 0;
-
- if (exp >= -14) {
- // normal fp32 to normal fp16
- exp = uint16_t(exp + uint16_t(15));
- u = uint16_t(((exp & 0x1f) << 10));
- u = uint16_t(u | (mantissa >> 13));
- } else {
- // normal single-precision to subnormal half_t-precision representation
- int rshift = (-14 - exp);
- if (rshift < 32) {
- mantissa |= (1 << 23);
-
- sticky_bit = ((mantissa & ((1 << rshift) - 1)) != 0);
-
- mantissa = (mantissa >> rshift);
- u = (uint16_t(mantissa >> 13) & 0x3ff);
- } else {
- mantissa = 0;
- u = 0;
- }
- }
-
- // round to nearest even
- int round_bit = ((mantissa >> 12) & 1);
- sticky_bit |= ((mantissa & ((1 << 12) - 1)) != 0);
-
- if ((round_bit && sticky_bit) || (round_bit && (u & 1))) {
- u = uint16_t(u + 1);
- }
-
- u |= sign;
-
- return cutlass::half_t::bitcast(u);
-}
-
-inline float cutlass::half_t::convert(unsigned short const& h) {
- int sign = ((h >> 15) & 1);
- int exp = ((h >> 10) & 0x1f);
- int mantissa = (h & 0x3ff);
- unsigned f = 0;
-
- if (exp > 0 && exp < 31) {
- // normal
- exp += 112;
- f = (sign << 31) | (exp << 23) | (mantissa << 13);
- } else if (exp == 0) {
- if (mantissa) {
- // subnormal
- exp += 113;
- while ((mantissa & (1 << 10)) == 0) {
- mantissa <<= 1;
- exp--;
- }
- mantissa &= 0x3ff;
- f = (sign << 31) | (exp << 23) | (mantissa << 13);
- } else {
- // sign-preserving zero
- f = (sign << 31);
- }
- } else if (exp == 31) {
- if (mantissa) {
- f = 0x7fffffff; // not a number
- } else {
- f = (0xff << 23) | (sign << 31); // inf
- }
- }
- return *reinterpret_cast<float const*>(&f);
-}
-
-inline cutlass::half_t::half_t() {}
-
-inline cutlass::half_t::half_t(int i) { x = convert(float(i)).x; }
-
-inline cutlass::half_t::half_t(float f) { x = convert(f).x; }
-
-inline cutlass::half_t::half_t(double d) { x = convert(float(d)).x; }
-
-inline bool cutlass::half_t::signbit() const { return (x >> 15) & 1; }
-
-inline int cutlass::half_t::exponent() const { return ((x >> 10) & 0x1f) - 15; }
-
-inline unsigned short cutlass::half_t::mantissa() const { return x & 0x3ff; }
-
-inline cutlass::half_t::operator bool() const { return (x & 0x7fff) != 0; }
-
-inline cutlass::half_t::operator int() const { return static_cast<int>(convert(x)); }
-
-inline cutlass::half_t::operator float() const { return convert(x); }
-
-inline cutlass::half_t::operator half() const { return cutlass::bitcast<half, unsigned short>(x); }
-
-inline bool cutlass::half_t::operator==(cutlass::half_t const& h) const {
- if (iszero() && h.iszero()) {
- return true;
- }
- return x == h.x;
-}
-
-inline bool cutlass::half_t::operator!=(cutlass::half_t const& h) const {
- if (iszero() && h.iszero()) {
- return false;
- }
- return x != h.x;
-}
-
-inline bool cutlass::half_t::operator==(float const& b) const { return x == half_t(b).x; }
-
-inline bool cutlass::half_t::operator!=(float const& b) const { return x != half_t(b).x; }
-
-inline bool cutlass::half_t::iszero() const { return (x & 0x7fff) == 0; }
-
-inline bool cutlass::half_t::isfinite() const { return (exponent() < 16); }
-
-inline bool cutlass::half_t::isnan() const {
- int exp = ((x >> 10) & 0x1f);
- if (exp == 0x1f) {
- return (x & 0x3ff) != 0;
- }
- return false;
-}
-
-inline bool cutlass::half_t::isinf() const {
- int exp = ((x >> 10) & 0x1f);
- if (exp == 0x1f) {
- return (x & 0x3ff) == 0;
- }
- return false;
-}
-
-inline bool cutlass::half_t::isnormal() const {
- int exp = exponent();
- return exp > -15 && exp < 16;
-}
-
-inline bool cutlass::half_t::operator<(half_t const& h) const {
- int sign = ((x >> 15) & 1);
- int h_sign = ((h.x >> 15) & 1);
- if (sign == h_sign) {
- return (x & 0x7fff) < (h.x & 0x7fff);
- } else if (sign) {
- return true;
- }
- return false;
-}
-
-inline bool cutlass::half_t::operator<=(half_t const& h) const {
- int sign = ((x >> 15) & 1);
- int h_sign = ((h.x >> 15) & 1);
- if (sign == h_sign) {
- return (x & 0x7fff) <= (h.x & 0x7fff);
- } else if (sign) {
- return true;
- }
- return false;
-}
-
-inline bool cutlass::half_t::operator>(half_t const& h) const {
- int sign = ((x >> 15) & 1);
- int h_sign = ((h.x >> 15) & 1);
- if (sign == h_sign) {
- return (x & 0x7fff) > (h.x & 0x7fff);
- } else if (h_sign) {
- return true;
- }
- return false;
-}
-
-inline bool cutlass::half_t::operator>=(half_t const& h) const {
- int sign = ((x >> 15) & 1);
- int h_sign = ((h.x >> 15) & 1);
- if (sign == h_sign) {
- return (x & 0x7fff) >= (h.x & 0x7fff);
- } else if (h_sign) {
- return true;
- }
- return false;
-}
-
-inline cutlass::half_t cutlass::half_t::operator+(cutlass::half_t const& b) const {
- return cutlass::half_t(float(*this) + float(b));
-}
-
-inline cutlass::half_t cutlass::half_t::operator-() const { return bitcast(x ^ 0x8000); }
-
-inline cutlass::half_t cutlass::half_t::operator-(cutlass::half_t const& b) const {
- return cutlass::half_t(float(*this) - float(b));
-}
-
-inline cutlass::half_t cutlass::half_t::operator*(cutlass::half_t const& b) const {
- return cutlass::half_t(float(*this) * float(b));
-}
-
-inline cutlass::half_t cutlass::half_t::operator/(cutlass::half_t const& b) const {
- return cutlass::half_t(float(*this) / float(b));
-}
-
-inline cutlass::half_t& cutlass::half_t::operator+=(cutlass::half_t const& b) {
- *this = cutlass::half_t(float(*this) + float(b));
- return *this;
-}
-
-inline cutlass::half_t& cutlass::half_t::operator-=(cutlass::half_t const& b) {
- *this = cutlass::half_t(float(*this) - float(b));
- return *this;
-}
-
-inline cutlass::half_t& cutlass::half_t::operator*=(cutlass::half_t const& b) {
- *this = cutlass::half_t(float(*this) * float(b));
- return *this;
-}
-
-inline cutlass::half_t& cutlass::half_t::operator/=(cutlass::half_t const& b) {
- *this = cutlass::half_t(float(*this) / float(b));
- return *this;
-}
-
-inline cutlass::half_t& cutlass::half_t::operator++() {
- *this = cutlass::half_t(float(*this) + 1.0f);
- return *this;
-}
-
-inline cutlass::half_t& cutlass::half_t::operator--() {
- *this = cutlass::half_t(float(*this) - 1.0f);
- return *this;
-}
-
-inline cutlass::half_t cutlass::half_t::operator++(int) {
- half_t h = *this;
- *this = cutlass::half_t(float(*this) + 1.0f);
- return h;
-}
-
-inline cutlass::half_t cutlass::half_t::operator--(int) {
- half_t h = *this;
- *this = cutlass::half_t(float(*this) - 1.0f);
- return h;
-}
-
-inline cutlass::half_t operator+(float a, cutlass::half_t const& b) {
- return cutlass::half_t(a + float(b));
-}
-
-inline cutlass::half_t operator-(float a, cutlass::half_t const& b) {
- return cutlass::half_t(a - float(b));
-}
-
-inline cutlass::half_t operator*(float a, cutlass::half_t const& b) {
- return cutlass::half_t(a * float(b));
-}
-
-inline cutlass::half_t operator/(float a, cutlass::half_t const& b) {
- return cutlass::half_t(a / float(b));
-}
-
-//
-//
-//
-
-inline cutlass::half2_t::half2_t() {}
-
-inline cutlass::half2_t::half2_t(half_t lo, half_t hi) : lo(lo), hi(hi) {}
-
-inline cutlass::half2_t::half2_t(std::pair<float, float> const& p) : lo(p.first), hi(p.second) {}
-
-inline cutlass::half2_t::half2_t(unsigned data)
- : lo(half_t::bitcast(uint16_t(data & 0x0ffff))),
- hi(half_t::bitcast(uint16_t((data >> 16) & 0x0ffff))) {}
-
-inline cutlass::half2_t cutlass::half2_t::operator+(half2_t const& b) const {
- return half2_t(lo + b.lo, hi + b.hi);
-}
-
-inline cutlass::half2_t cutlass::half2_t::operator-(half2_t const& b) const {
- return half2_t(lo - b.lo, hi - b.hi);
-}
-
-inline cutlass::half2_t cutlass::half2_t::operator*(half2_t const& b) const {
- return half2_t(lo * b.lo, hi * b.hi);
-}
-
-inline cutlass::half2_t cutlass::half2_t::operator/(half2_t const& b) const {
- return half2_t(lo / b.lo, hi / b.hi);
-}
-
-inline cutlass::half2_t& cutlass::half2_t::operator+=(half2_t const& b) {
- lo += b.lo;
- hi += b.hi;
- return *this;
-}
-
-inline cutlass::half2_t& cutlass::half2_t::operator-=(half2_t const& b) {
- lo -= b.lo;
- hi -= b.hi;
- return *this;
-}
-
-inline cutlass::half2_t& cutlass::half2_t::operator*=(half2_t const& b) {
- lo *= b.lo;
- hi *= b.hi;
- return *this;
-}
-
-inline cutlass::half2_t& cutlass::half2_t::operator/=(half2_t const& b) {
- lo /= b.lo;
- hi /= b.hi;
- return *this;
-}
-
-inline float cutlass::half2_t::dot(half2_t const& b) const {
- return float(lo) * float(b.lo) + float(hi) * float(b.hi);
-}
-
-inline float cutlass::half2_t::dot(half2_t const& b, float c) const { return c + dot(b); }
-
-inline cutlass::half_t cutlass::half2_t::doth(half2_t const& b) const {
- return cutlass::half_t(dot(b));
-}
-
-inline cutlass::half_t cutlass::half2_t::doth(half2_t const& b, half_t c) const {
- return cutlass::half_t(dot(b, float(c)));
-}
-
-inline cutlass::half2_t::operator std::pair<float, float>() const {
- return std::pair<float, float>(float(lo), float(hi));
-}
-
-inline unsigned cutlass::half2_t::packed() const { return (lo.x | (hi.x << 16)); }
-
-inline cutlass::half2_t::operator unsigned() const { return packed(); }
-
-//
-//
-//
-
-template <>
-inline float cutlass::bitcast<float, unsigned>(unsigned const& u) {
- return *reinterpret_cast<float const*>(&u);
-}
-
-template <>
-inline float cutlass::bitcast<float, int>(int const& i) {
- return *reinterpret_cast<float const*>(&i);
-}
-
-template <>
-inline unsigned cutlass::bitcast<unsigned, float>(float const& f) {
- return *reinterpret_cast<unsigned const*>(&f);
-}
-
-template <>
-inline cutlass::half_t cutlass::bitcast<cutlass::half_t, unsigned short>(unsigned short const& s) {
- return *reinterpret_cast<cutlass::half_t const*>(&s);
-}
-
-template <>
-inline unsigned short cutlass::bitcast<unsigned short, cutlass::half_t>(cutlass::half_t const& h) {
- return *reinterpret_cast<unsigned short const*>(&h);
-}
-
-template <>
-inline half cutlass::bitcast<half, unsigned short>(unsigned short const& s) {
- return *reinterpret_cast<half const*>(&s);
-}
-
-//
-// Lexical casts
-//
-
-#ifdef BOOST_LEXICAL_CAST_INCLUDED
-namespace boost {
-template <>
-cutlass::half_t lexical_cast<cutlass::half_t>(std::string const& arg) {
- return cutlass::half_t(boost::lexical_cast<float>(arg));
-}
-
-template <>
-std::string lexical_cast<std::string>(cutlass::half_t const& arg) {
- return boost::lexical_cast<std::string>(float(arg));
-}
-} // namespace boost
-#endif
-
-//
-// Standard Library Operations
-//
-
-// std
-namespace std {
-
-inline cutlass::half_t abs(cutlass::half_t const& h) {
- return cutlass::half_t::bitcast(h.x & 0x7fff);
-}
-
-inline bool isnan(cutlass::half_t const& h) { return h.isnan(); }
-
-inline bool isfinite(cutlass::half_t const& h) { return h.isfinite(); }
-
-inline cutlass::half_t nanh(const char*) { return cutlass::half_t::nan(); }
-
-inline bool isinf(cutlass::half_t const& h) { return h.isinf(); }
-
-inline bool isnormal(cutlass::half_t const& h) { return h.isnormal(); }
-
-inline int fpclassify(cutlass::half_t const& h) {
- int exp = h.exponent();
- unsigned short mantissa = h.mantissa();
- if (exp < -14) {
- if (mantissa == 0) {
- return FP_ZERO;
- } else {
- return FP_SUBNORMAL;
- }
- } else if (exp > 15) {
- if (mantissa == 0) {
- return FP_INFINITE;
- } else {
- return FP_NAN;
- }
- }
- return FP_NORMAL;
-}
-
-inline bool signbit(cutlass::half_t const& h) { return h.signbit(); }
-
-inline cutlass::half_t sqrt(cutlass::half_t const& h) {
- return cutlass::half_t(std::sqrt(float(h)));
-}
-} // namespace std
-
-//
-// Stream interactions
-//
-
-/// put to stream - half_t-precision types bitcast as unsigned shorts if base is hexadecimal
-inline std::ostream& operator<<(std::ostream& out, cutlass::half_t const& h) {
- if (out.flags() & std::ios::hex) {
- return out << h.x;
- } else {
- return out << float(h);
- }
-}
-
-/// read from stream - half_t-precision types parsed as unsigned shorts if base is hexadecimal
-inline std::istream& operator>>(std::istream& in, cutlass::half_t& h) {
- if (in.flags() & std::ios::hex) {
- unsigned short u = 0;
- in >> u;
- h = cutlass::half_t::bitcast(u);
- } else {
- float f = 0;
- in >> f;
- h = cutlass::half_t(f);
- }
- return in;
-}
diff --git a/cutlass-example/host_tensor.h b/cutlass-example/host_tensor.h
deleted file mode 100644
index 0936336..0000000
--- a/cutlass-example/host_tensor.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-#pragma once
-
-/*! \file
- \brief Template class to perform computations on tensors and manage memory.
-*/
-
-#include <cutlass/cutlass.h>
-#include <cutlass/matrix_traits.h>
-#include <device_memory.h>
-#include <host_tensor_view.h>
-#include <type_traits.h>
-#include <vector>
-
-namespace cutlass {
-
-template <typename T, bool DeviceBacked_ = true>
-class HostTensor : public HostTensorView<T> {
- public:
- /// Type used for device-side allocations
- typedef typename TypeTraits<T>::device_type DeviceType;
-
- /// Base class
- typedef HostTensorView<T> Base;
-
- /// If true, allocates device side memory
- static bool const DeviceBacked = DeviceBacked_;
-
- /// Rank of tensor
- static int const Rank = Base::Rank;
-
- /// Type used to compute the offset of an element to the base of a tensor
- typedef typename Base::Offset_t Offset_t;
-
- /// Tensor reference to host memory
- typedef typename Base::TensorRef_t TensorRef_t;
-
- /// Tensor reference to device memory
- typedef TensorRef<DeviceType, TensorRef_t::Rank> DeviceTensorRef;
-
- /// Tensor reference to constant device memory
- typedef TensorRef<DeviceType const, TensorRef_t::Rank> ConstDeviceTensorRef;
-
- /// Coordinate into tensor
- typedef typename Base::Coord_t Coord_t;
-
- private:
- /// Host-side memory allocation
- std::vector<T> host_;
-
- /// Device-side memory
- cutlass::device_memory::allocation<DeviceType> device_;
-
- public:
- //
- // Device and Host Methods
- //
-
- /// Default constructor
- HostTensor() {}
-
- /// Constructs a Tensor_view from stride and size
- HostTensor(Coord_t const& _stride, Coord_t const& _size) { reset(_stride, _size); }
-
- /// Constructs a HostTensor from size - infers strides
- HostTensor(Coord_t const& _size) {
- Coord_t _stride = make_Coord(
- _size.at(2) * _size.at(1) * _size.at(0), _size.at(1) * _size.at(0), _size.at(0), 1);
- reset(_stride, _size);
- }
-
- /// Returns the number of elements needed to back vector
- size_t capacity() { return Base::capacity(); }
-
- /// Returns true if the Tensor_view is bound to some memory
- bool good() const { return Base::good(); }
-
- /// Updates the reference and size of a Tensor_view object
- void reset(Coord_t const& _stride, Coord_t const& _size) {
- size_t _capacity = _size.at(0) * _stride.at(0);
-
- DeviceType* _device_memory = nullptr;
- if (DeviceBacked) {
- _device_memory = cutlass::device_memory::allocate<DeviceType>(_capacity);
- }
-
- host_.clear();
- host_.resize(_capacity);
- for (size_t i = 0; i < _capacity; ++i) {
- host_[i] = T((int)0xdeadbeef);
- }
- device_.reset(_device_memory, _capacity);
-
- Base::reset(TensorRef_t(host_.data(), _stride), _size);
- }
-
- /// Initializes the host tensor as a matrix
- void resize_matrix(int rows, int columns, MatrixLayout::Kind layout) {
- bool col_major = (layout == MatrixLayout::kColumnMajor);
- int ldm = (col_major ? rows : columns);
-
- Coord_t stride = make_Coord(rows * columns, col_major ? 1 : ldm, col_major ? ldm : 1, 1);
-
- Coord_t size = make_Coord(1, rows, columns, 1);
-
- reset(stride, size);
- }
-
- /// Simplifies resizing the host tensor
- void resize(int elements) { resize_matrix(1, elements, MatrixLayout::kColumnMajor); }
-
- /// Gets pointer to host data
- T const* host_data() const { return &host_[0]; }
-
- /// Gets pointer to host data
- T* host_data() { return &host_[0]; }
-
- /// Gets pointer to device data
- DeviceType* device_data() const { return device_.get(); }
-
- /// Copies data from device to host
- void sync_host() {
- if (DeviceBacked) {
- device_memory::copy_to_host(
- host_.data(), reinterpret_cast<T const*>(device_.get()), host_.size());
- }
- }
-
- /// Copies data from host to device
- void sync_device() {
- if (DeviceBacked) {
- device_memory::copy_to_device(
- device_.get(), reinterpret_cast<DeviceType const*>(host_.data()), host_.size());
- }
- }
-
- /// Copy data from a caller-supplied device pointer
- void copy_to_host(DeviceType const *ptr_device) {
- device_memory::copy_to_host(
- host_.data(), reinterpret_cast<T const *>(ptr_device), host_.size());
- }
-
- /// Copies data to a caller-supplied device pointer
- void copy_to_device(DeviceType *ptr_device) {
- device_memory::copy_to_device(
- ptr_device, reinterpret_cast<DeviceType const *>(host_.data()), host_.size());
- }
-
- /// Accesses the tensor reference pointing to data
- TensorRef_t& host_ref() { return Base::ref(); }
-
- /// Accesses the tensor reference pointing to data
- TensorRef_t const& host_ref() const { return Base::ref(); }
-
- /// Accesses the tensor reference pointing to data
- DeviceTensorRef device_ref() const { return DeviceTensorRef(device_data(), stride()); }
-
- /// Returns a tensor ref to constant memory on the device
- ConstDeviceTensorRef const_device_ref() const {
- return ConstDeviceTensorRef(device_data(), stride());
- }
-
- /// Accesses the size
- Coord_t const& size() const { return Base::size(); }
-
- /// Accesses the size
- int size(int dim) const { return Base::size(dim); }
-
- /// Accesses the size
- Coord_t const& stride() const { return Base::stride(); }
-
- /// Accesses the size
- int stride(int dim) const { return Base::stride(dim); }
-
- /// Returns the index of an element
- Offset_t offset(Coord_t const& coord) const { return Base::offset(coord); }
-
- /// Determines whether a location is within a tensor
- bool contains(Coord_t const& coord) const { return Base::contains(coord); }
-
- /// Element-wise accessor
- T& at(Coord_t const& coord) const { return Base::at(coord); }
-
- /// Element-wise accessor
- T& operator[](Coord_t const& coord) { return at(coord); }
-
- /// Element-wise accessor with basic offset
- T& at(int idx) const { return Base::at(idx); }
-
- /// Returns a Tensor_view given location and size quantities
- TensorView<T> subview(Coord_t const& _location, Coord_t _size) const {
- return Base::subview(_location, _size);
- }
-
- /// Recurses through all dimensions and applies a unary operation
- template <typename F>
- void elementwise_in_place(F& op, int dim = 0, Offset_t dst_offset_base = 0) {
- Base::elementwise_in_place(op, dim, dst_offset_base);
- }
-
- /// Recurses through all dimensions and applies a unary operator, supplying the logical
- /// coordinate within the tensor as an argument
- template <typename F>
- void elementwise_stream(F& op, int dim = 0, Offset_t dst_offset_base = 0) {
- Base::elementwise_stream(op, dim, dst_offset_base);
- }
-
- /// Recurses through all dimensions and applies a unary operator, supplying the logical
- /// coordinate within the tensor as an argument
- template <typename F>
- void elementwise_generate(F& op,
- int dim = 0,
- Offset_t dst_offset_base = 0,
- Coord_t coord = Coord_t(0)) {
- Base::elementwise_generate(op, dim, dst_offset_base, coord);
- }
-
- /// Recurses through all dimensions and applies a binary operation
- template <typename Src, typename F>
- bool elementwise_in_place(F& op,
- int dim,
- TensorView<Src> const& tensor,
- Offset_t dst_offset_base = 0,
- Offset_t src_offset_base = 0) {
- return Base::elementwise_in_place(op, dim, tensor, dst_offset_base, src_offset_base);
- }
-
- /// Accumulate in place
- template <typename Src>
- TensorView<T>& operator+=(TensorView<Src> const& tensor) {
- Base::operator+=(tensor);
- sync_device();
- return *this;
- }
-
- /// Subtract in place
- template <typename Src>
- TensorView<T>& operator-=(TensorView<Src> const& tensor) {
- Base::operator-=(tensor);
- sync_device();
- return *this;
- }
-
- /// Multiply in place
- template <typename Src>
- TensorView<T>& operator*=(TensorView<Src> const& tensor) {
- Base::operator*=(tensor);
- sync_device();
- return *this;
- }
-
- /// Divide in place
- template <typename Src>
- TensorView<T>& operator/=(TensorView<Src> const& tensor) {
- Base::operator/=(tensor);
- sync_device();
- return *this;
- }
-
- /// equality with epsilon tolerance
- bool equals(TensorView<T> const& tensor, T epsilon) const {
- return Base::equals(tensor, epsilon);
- }
-
- /// equality with ulps tolerance
- bool bit_equals(TensorView<T> const& tensor, long long ulps_threshold = 0) {
- return Base::bit_equals(tensor, ulps_threshold);
- }
-
- /// Computes general matrix product among select dimensions of a tensor
- /// Assumes:
- /// D: number of independent GEMMs to compute
- /// H: height of matrix
- /// W: width of matrix
- template <
- /// Data type of A matrix elements
- typename A,
- /// Data type of B matrix elements
- typename B,
- /// Data type of "compute" type (i.e. accumulator)
- typename Ctype,
- /// Data type of scale factors
- typename Stype>
- void gemm(TensorView<A> const& tensor_a, TensorView<B> const& tensor_b, Stype alpha, Stype beta) {
- Base::template gemm<A, B, Ctype, Stype>(tensor_a, tensor_b, alpha, beta);
- }
-
- /// Fills with random data
- template <typename Gen>
- void fill_random(Gen generator) {
- Base::fill_random(generator);
- sync_device();
- }
-
- /// Procedurally assigns elements
- template <typename Gen>
- void generate(Gen generator) {
- Base::generate(generator);
- sync_device();
- }
-
- /// Procedurally visits elements
- template <typename Gen>
- void visit(Gen& generator) const {
- Base::visit(generator);
- }
-
- /// initializes with identity
- void fill_identity() {
- Base::fill_identity();
- sync_device();
- }
-
- /// computes elements as a linear combination of their coordinates
- void fill_linear(Coord_t v, T offset = T(0)) {
- Base::fill_linear(v, offset);
- sync_device();
- }
-
- /// computes elements as a linear combination of their coordinates
- void fill_sequential(T v = T(1), T offset = T(0)) {
- Base::fill_sequential(v, offset);
- sync_device();
- }
-
- /// fills with a value
- void fill(T val = T(0)) {
- Base::fill(val);
- sync_device();
- }
-
- /// Copies from external data source and performs type conversion
- template <typename Src>
- void fill(TensorView<Src> const& tensor) {
- Base::fill(tensor);
- sync_device();
- }
-
- /// Computes the norm of the matrix in double-precision
- double norm() const { return Base::norm(); }
-};
-} // namespace cutlass
diff --git a/cutlass-example/host_tensor_view.h b/cutlass-example/host_tensor_view.h
deleted file mode 100644
index 56f02d3..0000000
--- a/cutlass-example/host_tensor_view.h
+++ /dev/null
@@ -1,542 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Host-side implementation of useful operations
-*/
-
-#pragma once
-
-#include <cutlass/cutlass.h>
-#include <cutlass/tensor_view.h>
-#include <type_traits.h>
-
-namespace cutlass {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename SrcType, typename DstType>
-struct Cast {
- static inline DstType apply(SrcType src) { return static_cast<DstType>(src); };
-};
-
-template <>
-struct Cast<float, int8_t> {
- static inline int8_t apply(float src) {
- return static_cast<int8_t>(fmaxf(-128.f, fminf(127.f, src)));
- };
-};
-
-template <>
-struct Cast<float, uint8_t> {
- static inline uint8_t apply(float src) {
- return static_cast<uint8_t>(fmaxf(0.f, fminf(255.f, src)));
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-class HostTensorView : public TensorView<T> {
- public:
- /// Base class
- typedef TensorView<T> TensorView_t;
-
- /// Convention: depth is the first dimension
- static int const Dim_D = 0;
-
- /// Convention: height is the second dimension
- static int const Dim_H = 1;
-
- /// Convention: width is the third dimension
- static int const Dim_W = 2;
-
- /// Convention: channel is the second dimension
- static int const Dim_C = 3;
-
- /// Rank of tensor
- static int const Rank = TensorView_t::Rank;
-
- /// Type used to compute the offset of an element to the base of a tensor
- typedef typename TensorView_t::Offset_t Offset_t;
-
- /// Reference and stride
- typedef typename TensorView_t::TensorRef_t TensorRef_t;
-
- /// Coordinate into tensor
- typedef typename TensorView_t::Coord_t Coord_t;
-
- public:
- //
- // Device and Host Methods
- //
-
- /// Default constructor
- HostTensorView() {}
-
- /// Constructs a Tensor_view from a TensorRef and size
- HostTensorView(TensorRef_t const& _ref, Coord_t const& _size) : TensorView_t(_ref, _size) {}
-
- /// Accesses the size
- Coord_t const& size() const { return TensorView_t::size(); }
-
- /// Accesses the size of a specified dimension
- int size(int dim) const { return size().at(dim); }
-
- /// Accesses the stride
- Coord_t const& stride() const { return TensorView_t::stride(); }
-
- /// Accesses the stride along a specified dimension
- int stride(int dim) const { return stride().at(dim); }
-
- /// Returns the number of scalar elements needed to store tensor
- size_t capacity() const { return size(3) * stride(3) * stride(2) * stride(1) * stride(0); }
-
- /// Returns true if the Tensor_view is bound to some memory
- bool good() const { return TensorView_t::good(); }
-
- /// Updates the reference and size of a TensorView object
- void reset(TensorRef_t const& _ref = TensorRef_t(0), Coord_t const& _size = Coord_t()) {
- return TensorView_t::reset(_ref, _size);
- }
-
- /// Accesses the tensor reference pointing to data
- TensorRef_t& ref() { return TensorView_t::ref(); }
-
- /// Accesses the tensor reference pointing to data
- TensorRef_t const& ref() const { return TensorView_t::ref(); }
-
- /// Assigns a tensor view
- HostTensorView& operator=(TensorView_t const& _tensor) {
- reset(_tensor.ref(), _tensor.size());
- return *this;
- }
-
- /// Returns the index of an element
- Offset_t offset(Coord_t const& coord) const { return TensorView_t::offset(coord); }
-
- /// Determines whether a location is within a tensor
- bool contains(Coord_t const& coord) const { return TensorView_t::contains(coord); }
-
- /// Element-wise accessor
- T& at(Coord_t const& coord) const { return TensorView_t::at(coord); }
-
- /// Element-wise accessor
- T& operator[](Coord_t const& coord) const { return at(coord); }
-
- /// Accesses an element with a raw offset
- T& at(int idx) const { return TensorView_t::at(idx); }
-
- /// Accesses an element with a raw offset
- T& operator[](int idx) const { return at(idx); }
-
- /// Returns a Tensor_view given location and size quantities
- TensorView_t subview(Coord_t const& location, Coord_t size) const {
- return TensorView_t::subview(location, size);
- }
-
- /// Recurses through all dimensions and applies a unary operation in place
- template <typename F>
- void elementwise_in_place(F& op, int dim = 0, Offset_t dst_offset_base = 0) {
- Offset_t dst_offset = dst_offset_base;
-
- for (int idx = 0; idx < size(dim); ++idx, dst_offset += stride(dim)) {
- if (dim < Rank - 1) {
- elementwise_in_place(op, dim + 1, dst_offset);
- } else {
- op(ref().data()[dst_offset]);
- }
- }
- }
-
- /// Recurses through all dimensions and applies a unary operator with no arguments
- template <typename F>
- void elementwise_stream(F& op, int dim = 0, Offset_t dst_offset_base = 0) {
- Offset_t dst_offset = dst_offset_base;
-
- for (int idx = 0; idx < size(dim); ++idx, dst_offset += stride(dim)) {
- if (dim < Rank - 1) {
- elementwise_stream(op, dim + 1, dst_offset);
- } else {
- ref().data()[dst_offset] = op();
- }
- }
- }
-
- /// Recurses through all dimensions and applies a unary operator, supplying the logical
- /// coordinate within the tensor as an argument
- template <typename F>
- void elementwise_generate(F& op,
- int dim = 0,
- Offset_t dst_offset_base = 0,
- Coord_t coord = Coord_t(0)) {
- Offset_t dst_offset = dst_offset_base;
-
- for (int idx = 0; idx < size(dim); ++idx, dst_offset += stride(dim)) {
- coord.at(dim) = idx;
-
- if (dim < Rank - 1) {
- elementwise_generate(op, dim + 1, dst_offset, coord);
- } else {
- ref().data()[dst_offset] = op(coord);
- }
- }
- }
-
- /// Recurses through all dimensions and applies a unary operator, supplying the logical
- /// coordinate within the tensor as an argument
- template <typename F>
- void elementwise_visit(F& op,
- int dim = 0,
- Offset_t dst_offset_base = 0,
- Coord_t coord = Coord_t(0)) const {
- Offset_t dst_offset = dst_offset_base;
-
- for (int idx = 0; idx < size(dim); ++idx, dst_offset += stride(dim)) {
- coord.at(dim) = idx;
-
- if (dim < Rank - 1) {
- elementwise_visit(op, dim + 1, dst_offset, coord);
- } else {
- op(ref().data()[dst_offset], coord);
- }
- }
- }
-
- /// Recurses through all dimensions and applies a binary operation
- template <typename Src, typename F>
- bool elementwise_in_place(F& op,
- TensorView<Src> const& tensor,
- int dim = 0,
- Offset_t dst_offset_base = 0,
- Offset_t src_offset_base = 0) {
- Offset_t dst_offset = dst_offset_base;
- Offset_t src_offset = src_offset_base;
-
- if (size().at(dim) != tensor.size().at(dim)) {
- return false;
- }
-
- for (int idx = 0; idx < size(dim);
- ++idx, dst_offset += stride(dim), src_offset += tensor.stride(dim)) {
- if (dim < Rank - 1) {
- elementwise_in_place(op, tensor, dim + 1, dst_offset, src_offset);
- } else {
- op(data()[dst_offset], tensor.data()[src_offset]);
- }
- }
-
- return true;
- }
-
- template <typename Src>
- struct LambdaBinaryAddition {
- void operator()(T& a, Src b) const { a += T(b); }
- };
-
- template <typename Src>
- struct LambdaBinarySubtraction {
- void operator()(T& a, Src b) const { a -= T(b); }
- };
-
- template <typename Src>
- struct LambdaBinaryMultiplication {
- void operator()(T& a, Src b) const { a *= T(b); }
- };
-
- template <typename Src>
- struct LambdaBinaryDivision {
- void operator()(T& a, Src b) const { a /= T(b); }
- };
-
- /// Accumulate in place
- template <typename Src>
- TensorView<T>& operator+=(TensorView<Src> const& tensor) {
- LambdaBinaryAddition<Src> op;
- elementwise_in_place(op, tensor);
-
- return *this;
- }
-
- /// Subtract in place
- template <typename Src>
- TensorView<T>& operator-=(TensorView<Src> const& tensor) {
- LambdaBinarySubtraction<Src> op;
- elementwise_in_place(op, tensor);
-
- return *this;
- }
-
- /// Multiply in place
- template <typename Src>
- TensorView<T>& operator*=(TensorView<Src> const& tensor) {
- LambdaBinaryMultiplication<Src> op;
- elementwise_in_place(op, tensor);
-
- return *this;
- }
-
- /// Divide in place
- template <typename Src>
- TensorView<T>& operator/=(TensorView<Src> const& tensor) {
- LambdaBinaryDivision<Src> op;
- elementwise_in_place(op, tensor);
-
- return *this;
- }
-
- /// Comparison operator
- struct EqualsOperator {
- bool equal;
- T eps;
-
- EqualsOperator(T _epsilon) : equal(true), eps(_epsilon) {}
-
- void operator()(T a, T b) {
- if (std::abs(T(a - b)) > eps * std::max(std::abs(a), std::abs(b))) {
- equal = false;
- }
- }
- };
-
- /// equality with epsilon tolerance
- bool equals(TensorView<T> const& tensor, T epsilon) const {
- EqualsOperator comparison_op(epsilon);
- bool equal_size = elementwise_in_place(comparison_op, tensor);
-
- return equal_size && comparison_op.equal;
- }
-
- /// Compares two values which are smaller or equal to a long long int
- struct BitEqualsOperator {
- bool equal;
- long long eps;
- uint64_t index;
-
- BitEqualsOperator(long long _ulps_threshold) : equal(true), eps(_ulps_threshold), index(0) {}
-
- void operator()(T a, T b) {
- // convert bits to integers
- long long bits_a = 0;
- long long bits_b = 0;
-
- *reinterpret_cast<T*>(&bits_a) = TypeTraits<T>::remove_negative_zero(a);
- *reinterpret_cast<T*>(&bits_b) = TypeTraits<T>::remove_negative_zero(b);
-
- // compute diff
- long long ulps = bits_a - bits_b;
- if (std::abs(ulps) > eps) {
- equal = false;
- }
- index++;
- }
- };
-
- /// equality with ulps tolerance
- bool bit_equals(TensorView<T> const& tensor, long long ulps_threshold = 0) {
- BitEqualsOperator comparison_op(ulps_threshold);
- bool equal_size = elementwise_in_place(comparison_op, tensor);
-
- return equal_size && comparison_op.equal;
- }
-
- /// Gets naked pointer to data
- T* data() const { return TensorView_t::data(); }
-
- /// Computes general matrix product among select dimensions of a tensor
- /// Assumes:
- /// D: number of independent GEMMs to compute
- /// H: height of matrix
- /// W: width of matrix
- /// C: "channels" of each element
- template <typename A, typename B, typename Ctype, typename Stype>
- void gemm(TensorView<A> const& tensor_a, TensorView<B> const& tensor_b, Stype alpha, Stype beta) {
- int const Batch = size(Dim_D);
- int const M = size(Dim_H);
- int const N = size(Dim_W);
- int const K = tensor_a.size(Dim_W);
- int const C = tensor_a.size(Dim_C);
-
- // Sizes must match
- if (tensor_a.size(Dim_H) != M || tensor_b.size(Dim_W) != N || tensor_b.size(Dim_C) != C ||
- tensor_b.size(Dim_H) != K) {
- return;
- }
-
- int const Mblock = 32;
- int const Nblock = 32;
-
- for (int batch = 0; batch < Batch; ++batch) {
- for (int row_block = 0; row_block < M; row_block += Mblock) {
- for (int col_block = 0; col_block < N; col_block += Nblock) {
- Ctype accum[Mblock][Nblock];
-
- for (int j = 0; j < Nblock; j++) {
- for (int i = 0; i < Mblock; i++) {
- accum[i][j] = Ctype(0);
- }
- }
-
- for (int k_block = 0; k_block < K; ++k_block) {
- for (int j = 0; j < Nblock; j++) {
- for (int i = 0; i < Mblock; i++) {
- int row = row_block + i;
- int col = col_block + j;
-
- if (row < M && col < N) {
- for (int channel = 0; channel < C; ++channel) {
- Ctype a(tensor_a.at(make_Coord(batch, row, k_block, channel)));
- Ctype b(tensor_b.at(make_Coord(batch, k_block, col, channel)));
-
- accum[i][j] += a * b;
- }
- }
- }
- }
- }
-
- for (int j = 0; j < Nblock; j++) {
- for (int i = 0; i < Mblock; i++) {
- int row = row_block + i;
- int col = col_block + j;
-
- Coord_t coord = make_Coord(batch, row, col, 0);
- if (row < M && col < N) {
- at(coord) =
- Cast<Stype, T>::apply(alpha * Stype(accum[i][j]) + beta * Stype(at(coord)));
- }
- }
- }
- }
- }
- }
- }
-
- /// Fills with random data
- template <typename Gen>
- void fill_random(Gen generator) {
- elementwise_stream(generator);
- }
-
- /// Procedurally assigns elements
- template <typename Gen>
- void generate(Gen generator) {
- elementwise_generate(generator);
- }
-
- /// Procedurally visits elements
- template <typename Gen>
- void visit(Gen& generator) const {
- elementwise_visit(generator);
- }
-
- /// Generator to fill a tensor with the identity matrix
- struct LambdaFillIdentity {
- T operator()(Coord_t const& coord) { return (coord.at(1) == coord.at(2) ? T(1) : T(0)); }
- };
-
- /// initializes with identity
- void fill_identity() {
- LambdaFillIdentity op;
- elementwise_generate(op);
- }
-
- /// Lambda for fill_linear()
- struct LambdaFillLinear {
- Coord_t v_;
- T offset_;
-
- LambdaFillLinear(Coord_t const& _v, T _offset) : v_(_v), offset_(_offset) {}
-
- T operator()(Coord_t const& coord) { return T(v_.template dot<int>(coord)) + offset_; }
- };
-
- /// computes elements as a linear combination of their coordinates
- void fill_linear(Coord_t v, T offset = T(0)) {
- LambdaFillLinear lambda(v, offset);
- elementwise_generate(lambda);
- }
-
- /// computes elements as a linear combination of their coordinates
- void fill_sequential(T v = T(1), T offset = T(0)) {
- int const count = size().count();
- for (int i = 0; i < count; ++i) {
- data()[i] = T(i);
- }
- }
-
- /// Returns a constant value
- struct LambdaFillValue {
- T value;
-
- LambdaFillValue(T _value) : value(_value) {}
-
- T operator()() { return value; }
- };
-
- /// fills with a value
- void fill(T val = T(0)) {
- LambdaFillValue op(val);
- elementwise_stream(op);
- }
-
- /// Conversion from Src to T
- template <typename Src>
- struct LambdaAssign {
- void operator()(T& a, Src b) const { a = T(b); }
- };
-
- /// copies from external data source and performs type conversion
- template <typename Src>
- void fill(TensorView<Src> const& tensor) {
- LambdaAssign<Src> op;
- elementwise_in_place(op, tensor);
- }
-
- /// Computes a norm
- struct LambdaNorm {
- double sum;
-
- LambdaNorm() : sum(0) {}
-
- void operator()(T const& element) {
- double value(element);
- double conj(element); // TODO - conjugates for complex
-
- sum += value * conj;
- }
- };
-
- /// Computes the norm of the matrix in double-precision
- double norm() const {
- LambdaNorm op;
- elementwise_in_place(op);
-
- return std::sqrt(op.sum);
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-} // namespace cutlass
diff --git a/cutlass-example/launch.sh b/cutlass-example/launch.sh
deleted file mode 100755
index e48f53e..0000000
--- a/cutlass-example/launch.sh
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/bin/bash
-make clean
-make CFLAGS=-DWMMA_GEMM_16x16x16_NT
-./myprog > LOG_WMMA_GEMM_16x16x16_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_16x16x32_NT
-./myprog > LOG_WMMA_GEMM_16x16x32_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_16x16x16_NN
-./myprog > LOG_WMMA_GEMM_16x16x16_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_16x16x32_NN
-./myprog > LOG_WMMA_GEMM_16x16x32_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_16x16x16_TT
-./myprog > LOG_WMMA_GEMM_16x16x16_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_16x16x32_TT
-./myprog > LOG_WMMA_GEMM_16x16x32_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_16x16x16_TN
-./myprog > LOG_WMMA_GEMM_16x16x16_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_16x16x32_TN
-./myprog > LOG_WMMA_GEMM_16x16x32_TN
-make clean
-make CFLAGS=-DWMMA_16x16x16_GEMM_256x256x128_NT
-./myprog > LOG_WMMA_16x16x16_GEMM_256x256x128_NT
-make clean
-make CFLAGS=-DWMMA_16x16x16_GEMM_256x256x128_NN
-./myprog > LOG_WMMA_16x16x16_GEMM_256x256x128_NN
-make clean
-make CFLAGS=-DWMMA_16x16x16_GEMM_256x256x128_TT
-./myprog > LOG_WMMA_16x16x16_GEMM_256x256x128_TT
-make clean
-make CFLAGS=-DWMMA_16x16x16_GEMM_256x256x128_TN
-./myprog > LOG_WMMA_16x16x16_GEMM_256x256x128_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_256x256x256_NT
-./myprog > LOG_WMMA_GEMM_256x256x256_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_256x256x256_NN
-./myprog > LOG_WMMA_GEMM_256x256x256_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_256x256x256_TT
-./myprog > LOG_WMMA_GEMM_256x256x256_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_256x256x256_TN
-./myprog > LOG_WMMA_GEMM_256x256x256_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_512x512x512_NT
-./myprog > LOG_WMMA_GEMM_512x512x512_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_512x512x512_NN
-./myprog > LOG_WMMA_GEMM_512x512x512_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_512x512x512_TT
-./myprog > LOG_WMMA_GEMM_512x512x512_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_512x512x512_TN
-./myprog > LOG_WMMA_GEMM_512x512x512_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_1024x1024x1024_NT
-./myprog > LOG_WMMA_GEMM_1024x1024x1024_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_1024x1024x1024_NN
-./myprog > LOG_WMMA_GEMM_1024x1024x1024_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_1024x1024x1024_TT
-./myprog > LOG_WMMA_GEMM_1024x1024x1024_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_1024x1024x1024_TN
-./myprog > LOG_WMMA_GEMM_1024x1024x1024_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_2048x2048x2048_NT
-./myprog > LOG_WMMA_GEMM_2048x2048x2048_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_2048x2048x2048_NN
-./myprog > LOG_WMMA_GEMM_2048x2048x2048_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_2048x2048x2048_TT
-./myprog > LOG_WMMA_GEMM_2048x2048x2048_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_2048x2048x2048_TN
-./myprog > LOG_WMMA_GEMM_2048x2048x2048_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_4096x4096x4096_NT
-./myprog > LOG_WMMA_GEMM_4096x4096x4096_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_4096x4096x4096_NN
-./myprog > LOG_WMMA_GEMM_4096x4096x4096_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_4096x4096x4096_TT
-./myprog > LOG_WMMA_GEMM_4096x4096x4096_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_4096x4096x4096_TN
-./myprog > LOG_WMMA_GEMM_4096x4096x4096_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_32x32x32_NT
-./myprog > LOG_WMMA_GEMM_32x32x32_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_32x32x32_NN
-./myprog > LOG_WMMA_GEMM_32x32x32_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_32x32x32_TT
-./myprog > LOG_WMMA_GEMM_32x32x32_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_32x32x32_TN
-./myprog > LOG_WMMA_GEMM_32x32x32_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_128x128x128_NT
-./myprog > LOG_WMMA_GEMM_128x128x128_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_128x128x128_NN
-./myprog > LOG_WMMA_GEMM_128x128x128_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_128x128x128_TT
-./myprog > LOG_WMMA_GEMM_128x128x128_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_128x128x128_TN
-./myprog > LOG_WMMA_GEMM_128x128x128_TN
-make clean
-make CFLAGS=-DWMMA_GEMM_768x768x768_NT
-./myprog > LOG_WMMA_GEMM_768x768x768_NT
-make clean
-make CFLAGS=-DWMMA_GEMM_768x768x768_NN
-./myprog > LOG_WMMA_GEMM_768x768x768_NN
-make clean
-make CFLAGS=-DWMMA_GEMM_768x768x768_TT
-./myprog > LOG_WMMA_GEMM_768x768x768_TT
-make clean
-make CFLAGS=-DWMMA_GEMM_768x768x768_TN
-./myprog > LOG_WMMA_GEMM_768x768x768_TN
-make clean
diff --git a/cutlass-example/tensor_view_io.h b/cutlass-example/tensor_view_io.h
deleted file mode 100644
index bc2e9b1..0000000
--- a/cutlass-example/tensor_view_io.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/***************************************************************************************************
-* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted
-* provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright notice, this list of
-* conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright notice, this list of
-* conditions and the following disclaimer in the documentation and/or other materials
-* provided with the distribution.
-* * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
-* to endorse or promote products derived from this software without specific prior written
-* permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
-* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
-* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-**************************************************************************************************/
-#pragma once
-
-#include <cutlass/core_io.h>
-#include <cutlass/tensor_view.h>
-
-template <typename T>
-inline std::ostream& tensor_view_output(std::ostream& out, T t) {
- out << t;
- return out;
-}
-
-template <>
-inline std::ostream& tensor_view_output<int8_t>(std::ostream& out, int8_t t) {
- out << int(t);
- return out;
-}
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out, cutlass::TensorView<T> const& tensor) {
- for (int batch = 0; batch < tensor.size(0); ++batch) {
- out << "[\n ";
- for (int h = 0; h < tensor.size(1); ++h) {
- for (int w = 0; w < tensor.size(2); ++w) {
- for (int c = 0; c < tensor.size(3); ++c) {
- out << ((c | w) ? " " : "");
- tensor_view_output(out, tensor.at(cutlass::make_Coord(batch, h, w, c)));
- }
- }
- if (h + 1 < tensor.size(1)) {
- out << " ;\n ";
- }
- }
- out << " ]";
- }
-
- return out;
-}
diff --git a/cutlass-example/type_traits.h b/cutlass-example/type_traits.h
deleted file mode 100644
index eabd67e..0000000
--- a/cutlass-example/type_traits.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/***************************************************************************************************
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted
- * provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************************/
-/*! \file
- \brief Type traits for common CUDA types
-*/
-
-#pragma once
-
-#include <cuda_fp16.h>
-#include <stdint.h>
-
-#include "half.h"
-
-namespace cutlass {
-struct half_t;
-
-template <typename T>
-struct TypeTraits;
-
-template <>
-struct TypeTraits<int8_t> {
-// static cudaDataType_t const cublas_type = CUDA_R_8I;
- typedef int8_t host_type;
- typedef int8_t device_type;
- typedef int8_t integer_type;
- typedef uint8_t unsigned_type;
- static inline int8_t remove_negative_zero(int8_t x) { return x; }
- static inline int to_print(int8_t x) { return (int)x; }
-};
-
-template <>
-struct TypeTraits<uint8_t> {
-// static cudaDataType_t const cublas_type = CUDA_R_8I;
- typedef uint8_t host_type;
- typedef uint8_t device_type;
- typedef uint8_t integer_type;
- typedef uint8_t unsigned_type;
- static inline uint8_t remove_negative_zero(uint8_t x) { return x; }
- static inline uint32_t to_print(uint8_t x) { return (uint32_t)x; }
-};
-
-template <>
-struct TypeTraits<int> {
-// static cudaDataType_t const cublas_type = CUDA_R_32I;
- typedef int host_type;
- typedef int device_type;
- typedef int32_t integer_type;
- typedef uint32_t unsigned_type;
- static inline int32_t remove_negative_zero(int32_t x) { return x; }
- static inline int to_print(int x) { return x; }
-};
-
-template <>
-struct TypeTraits<unsigned> {
-// static cudaDataType_t const cublas_type = CUDA_R_32I;
- typedef unsigned host_type;
- typedef unsigned device_type;
- typedef uint32_t integer_type;
- typedef uint32_t unsigned_type;
- static inline uint32_t remove_negative_zero(uint32_t x) { return x; }
- static inline uint32_t to_print(uint32_t x) { return x; }
-};
-
-template <>
-struct TypeTraits<half> {
-// static cudaDataType_t const cublas_type = CUDA_R_16F;
- typedef half_t host_type;
- typedef half device_type;
- typedef int16_t integer_type;
- typedef uint16_t unsigned_type;
- static inline half remove_negative_zero(half x) {
- integer_type h_int = reinterpret_cast<integer_type const&>(x);
- if (h_int == 0x8000) {
- h_int = 0;
- }
- x = reinterpret_cast<half const&>(h_int);
- return x;
- }
- static inline half to_print(half x) { return x; }
-};
-
-template <>
-struct TypeTraits<int64_t> {
-// static cudaDataType_t const cublas_type = CUDA_R_8I;
- typedef int64_t host_type;
- typedef int64_t device_type;
- typedef int64_t integer_type;
- typedef uint64_t unsigned_type;
- static inline int64_t remove_negative_zero(int64_t x) { return x; }
- static inline int64_t to_print(int64_t x) { return x; }
-};
-
-template <>
-struct TypeTraits<uint64_t> {
-// static cudaDataType_t const cublas_type = CUDA_R_8I;
- typedef uint64_t host_type;
- typedef uint64_t device_type;
- typedef uint64_t integer_type;
- typedef uint64_t unsigned_type;
- static inline uint64_t remove_negative_zero(uint64_t x) { return x; }
- static inline uint64_t to_print(uint64_t x) { return x; }
-};
-
-template <>
-struct TypeTraits<cutlass::half_t> {
-// static cudaDataType_t const cublas_type = CUDA_R_16F;
- typedef half_t host_type;
- typedef half device_type;
- typedef int16_t integer_type;
- typedef uint16_t unsigned_type;
- static inline half_t remove_negative_zero(half_t x) {
- return (x.raw() == 0x8000 ? half_t::bitcast(0) : x);
- }
- static inline half_t to_print(half_t x) { return x; }
-};
-
-template <>
-struct TypeTraits<float> {
-// static cudaDataType_t const cublas_type = CUDA_R_32F;
- typedef float host_type;
- typedef float device_type;
- typedef int32_t integer_type;
- typedef uint32_t unsigned_type;
- static inline float remove_negative_zero(float x) { return x == -0.f ? 0.f : x; }
- static inline float to_print(float x) { return x; }
-};
-
-template <>
-struct TypeTraits<double> {
-// static cudaDataType_t const cublas_type = CUDA_R_64F;
- typedef double host_type;
- typedef double device_type;
- typedef int64_t integer_type;
- typedef uint64_t unsigned_type;
- static inline double remove_negative_zero(double x) { return x == -0.0 ? 0.0 : x; }
- static inline double to_print(double x) { return x; }
-};
-} // namespace cutlass