
Pechkin80
Пользователи-
Content count
72 -
Joined
-
Last visited
-
Days Won
1
-
Оптимальное распараллеливание для CUDA для операции свёртки.
Pechkin80 posted a topic in Обсуждение общих вопросов
Добрый день, Хочу на простом примере распараллеливания операции свёртки понять как выбирать оптимальные значения для числа блоков, числа нитей и кошерно ли делать цикл внутри нити или надо максимально увеличить число блоков и нитей ? Допустим матрица размером M*N Допустим число ядер cuda, известное из документации. Пока понял что для случая большой матрицы(изображения) лучше топить на число нитей в блоке так как всю её за раз не посчитаешь и планировщик нитей в варпе должен работать по идеи быстрей планировщика блоков, но кто быстрей внутренний цикл в ните или планировщик блоков ? Когда матрица маленькая и может посчитаться за один цикл(распараллевание не больше чем число ядер), то я так понимаю надо наоборот число нитей надо брать в 1 варп(32), а число блоков надо брать число ядер/32. -
Спасибо. с пайплайном почти разобрался. Еслибы ещё входной и выходной тензор у тф научился бы окунать в gpu, то былобы вообще супер.
-
А на джетсоне они тоже из этого сиска ?
-
А видеокарта какая у тебя ? Моей (940М) тупо нет в списке https://developer.nvidia.com/video-encode-decode-gpu-support-matrix#Decoder
-
const char * imagefilename = "Image_paint.jpg"; static AVFormatContext *fmt_ctx = nullptr; static AVCodecContext *dec_ctx = nullptr; static int video_stream_index = -1; static int open_input_file(const char *filename = videofilename) { /* avcodec_register_all(); AVCodec* codec = avcodec_find_decoder_by_name("mpeg4_cuvid"); AVCodecContext * avctx = avcodec_alloc_context3(codec); avctx->pix_fmt = AV_PIX_FMT_CUDA; */ int ret; AVCodec *dec; if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n"); return ret; } if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n"); return ret; } /* select the video stream */ ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n"); return ret; } video_stream_index = ret; dec_ctx = fmt_ctx->streams[video_stream_index]->codec; av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0); std::cout << avcodec_get_name(fmt_ctx->streams[video_stream_index]->codecpar->codec_id) << ": " << fmt_ctx->streams[video_stream_index]->codecpar->codec_id << std::endl; avcodec_register_all(); AVCodec* codec = avcodec_find_decoder_by_name("mpeg4_cuvid"); if (codec != nullptr) { std::cout << "codec found" << std::endl; } fmt_ctx->streams[video_stream_index]->codecpar->codec_id = codec->id; fmt_ctx->streams[video_stream_index]->id = codec->id; fmt_ctx->streams[video_stream_index]->codecpar->codec_type = codec->type; //fmt_ctx->streams[video_stream_index]->codecpar->format = *codec->pix_fmts; fmt_ctx->streams[video_stream_index]->codec->codec_id = codec->id; fmt_ctx->streams[video_stream_index]->codec->codec_type = codec->type; fmt_ctx->streams[video_stream_index]->codecpar->format = AV_PIX_FMT_CUDA; dec_ctx = fmt_ctx->streams[video_stream_index]->codec; dec_ctx->pix_fmt = AV_PIX_FMT_CUDA; ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0); std::cout << avcodec_get_name(fmt_ctx->streams[video_stream_index]->codecpar->codec_id) << ": " << fmt_ctx->streams[video_stream_index]->codecpar->codec_id << std::endl; //AVCodecContext * avctx = avcodec_alloc_context3(codec); //dec_ctx = avctx; //dec = codec; //avctx->pix_fmt = AV_PIX_FMT_CUDA; //if (avcodec_open2(avctx, codec, opts) < 0) // return; /* init the video decoder */ if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n"); return ret; } AVFrame *mpDecodedFrame = av_frame_alloc(); int got; AVPacket tsPkt; av_init_packet(&tsPkt); avcodec_decode_video2(dec_ctx, mpDecodedFrame, &got, &tsPkt); return 0; } Вот так исполняется без ошибок, но надо понять как реализовать считывание кадра за кадром, и вдобавок как сделать перемотку назад.
-
У меня нет переменной stream в коде. Код: std::cout << avcodec_get_name(fmt_ctx->streams[video_stream_index]->codecpar->codec_id) << ": " << fmt_ctx->streams[video_stream_index]->codecpar->codec_id << std::endl; Выдаёт: mpeg4: 13 Сама структура ...->streams[video_stream_index]->codec; определена как деприкейтед и на замену предлогают streams[video_stream_index]->codecpar
-
сам собирал.
-
Дошли руки попробовать, но тут не сказано как это должно быть связано с загрузкой видеофайла или захвата видеопотока. Моя попытка успехом не увенчалась: static AVFormatContext *fmt_ctx = nullptr; static AVCodecContext *dec_ctx = nullptr; static int video_stream_index = -1; static int open_input_file(const char *filename = videofilename) { int ret; AVCodec *dec; if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n"); return ret; } if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n"); return ret; } /* select the video stream */ ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n"); return ret; } video_stream_index = ret; dec_ctx = fmt_ctx->streams[video_stream_index]->codec; av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0); avcodec_register_all(); AVCodec* codec = avcodec_find_decoder_by_name("h264_cuvid"); AVCodecContext * avctx = avcodec_alloc_context3(codec); dec_ctx = avctx; dec = codec; avctx->pix_fmt = AV_PIX_FMT_CUDA; //if (avcodec_open2(avctx, codec, opts) < 0) // return; /* init the video decoder */ if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n"); return ret; } return 0; } Вывод приложения: Вывод утилиты:
-
Определение размерности входного и выходного узла графа.
Pechkin80 replied to Pechkin80's topic in Вопросы по нейросетям и ИИ
Кажеться разобрался как разрулить с логами без перекомпиляции. Поторопился. Без перекомпиляции кажеться нереально. Там как я понял создаётся временный объект tensorflow/core/platform/default/logging.h И по сути никаких логов там не ведётся. -
Определение размерности входного и выходного узла графа.
Pechkin80 replied to Pechkin80's topic in Вопросы по нейросетям и ИИ
Да эт я знаю, но программа может иметь свои сообщения. Хочеться не на уровне окружения(оболочки) решать вопрос. есть класс SessionLog, причём как в питоне так и в плюсах. Ну не хочет пока выдавать лог. -
Определение размерности входного и выходного узла графа.
Pechkin80 replied to Pechkin80's topic in Вопросы по нейросетям и ИИ
Не уверен что понял вопрос. Щас пилю инференс. Там много вещей, которые нужны в любой задаче. Особенно для меня загадка как аккуратно распределить GPU память между tensorflow, opencv, ffmpeg. Предпологаеться что каждая либа будет использовать куду. Надо както расчитать сколько нужно памяти для модели. Ну а прямо щас копаю как перенаправить логи, а то пишет много всего, но в терминал. -
Определение размерности входного и выходного узла графа.
Pechkin80 replied to Pechkin80's topic in Вопросы по нейросетям и ИИ
Да всё, проблема с размерностью решена. Щас осталось разобраться как контрлировать процесс с памятью для GPU и перенаправлений логов сессии в файл. -
Определение размерности входного и выходного узла графа.
Pechkin80 replied to Pechkin80's topic in Вопросы по нейросетям и ИИ
А вот так почти сработало, только понять бы в чём разница с предыдущем вариантом. const auto size1 = 1; const auto size2 = 192; const auto size3 = 512; const auto size4 = 1; Tensor inputTensor1(DT_FLOAT, TensorShape({size1, size2, size3, size4})); //заполнение тензоров-входных данных for (int i1 = 0; i1 < size2; i1++) { for (int j1 = 0; j1 < size3; j1++) { inputTensor1.tensor<float, 4>()(0, i1, j1, 0) = 128.; } } Теперь с GPU воевать придёться: UPDATE: В предыдущем сообщении была ошибка: вместо auto intensor = graph_def.node(1).attr().at("shape"); надо: auto intensor = graph_def.node(1).attr().at("value"); -
Определение размерности входного и выходного узла графа.
Pechkin80 replied to Pechkin80's topic in Вопросы по нейросетям и ИИ
Пока забил вручную: Но я не врублюсь какой размерности тензор создавать. В питоне было [-1, 192, 512, 1], а в плюсах const auto size1 = 0; const auto size2 = 192; const auto size3 = 512; const auto size4 = 1; Tensor inputTensor1(DT_FLOAT, TensorShape({size1, size2, size3, size4})); если создать с размерностью (0, 192, 512, 1) то при такой иннициаллизации: for (int i1 = 0; i1 < size2; i1++) { for (int j1 = 0; j1 < size3; j1++) { inputTensor1.matrix<float>()(i1, j1) = 128; } } я получаю ошибку времени выполнения : А при такой иннициаллизации: for (int i1 = 0; i1 < size2; i1++) { for (int j1 = 0; j1 < size3; j1++) { inputTensor1.matrix<float>()(0, i1, j1, 0) = 128; } } такую на этапе компиляции: Вообщем очень сильно плаваю в ситуации, поэто и хотел задавать размерность на автомате чтоб меньше ошибаться. UPDATE: Я на самом деле вроде придумал как определять размерность и если я прав, то всё очень грустно, потомучто тензор в файле записан одномерным. auto intensor = graph_def.node(1).attr().at("value"); Tensor tmp_tensor; bool result = tmp_tensor.FromProto(intensor); int num_dimensions = tmp_tensor.shape().dims(); std::cerr << num_dimensions << std::endl; for(int ii_dim = 0; ii_dim < num_dimensions; ii_dim++) { std::cerr << "i" << tmp_tensor.shape().dim_size(ii_dim) << std::endl; } Потомучто я имею на любом узле num_dimensions равное единице. -
Определение размерности входного и выходного узла графа.
Pechkin80 replied to Pechkin80's topic in Вопросы по нейросетям и ИИ
А C API можно миксить с С++ API ? Вот тут интересные рассуждения.