#include <iostream>

#define TO_K(X) X / 1000
#define TO_G(X) X / 1000000000
#define FMT_3D(X) "(" << (X)[0] << ", " << (X)[1] << ", " << (X)[2] << ")"

int main(int argc, char const *argv[])
{
    // step 01
    int device_count = -1;
    cudaGetDeviceCount(&device_count);

    std::cout << "device_count = " << device_count << "\n";

    for (auto i = 0; i < device_count; ++i)
    {
        std::cout << "device [" << i << "]:\n";

        struct cudaDeviceProp device_prop;
        cudaGetDeviceProperties(&device_prop, i);

        std::cout << "\t'device_prop.name' : " << device_prop.name << "\n";
        std::cout << "\t'device_prop.totalGlobalMem' : " << TO_G(device_prop.totalGlobalMem) << "\n";
        std::cout << "\t'device_prop.sharedMemPerBlock' : " << TO_K(device_prop.sharedMemPerBlock) << "\n";
        std::cout << "\t'device_prop.maxThreadsPerBlock' : " << device_prop.maxThreadsPerBlock << "\n";
        std::cout << "\t'device_prop.maxThreadsDim' : " << FMT_3D(device_prop.maxThreadsDim) << "\n";
        std::cout << "\t'device_prop.maxGridSize' : " << FMT_3D(device_prop.maxGridSize) << "\n";
        std::cout << "\t'(device_prop.major, device_prop.minor)' : " << device_prop.major << "." << device_prop.minor << "\n";
        std::cout << "\t'device_prop.warpSize' : " << device_prop.warpSize << "\n";
        std::cout << "\t'device_prop.regsPerBlock' : " << device_prop.regsPerBlock << "\n";
        std::cout << "\t'device_prop.multiProcessorCount' : " << device_prop.multiProcessorCount << "\n";

    }

    return 0;
}

// # Question 1
// Avec 49152 octets de mémoire par bloc, il est possible de stocker 49152/4 = 12288 nombres flotants 32bit.
